Skip to content

Commit 27b5ae2

Browse files
zeyapmeta-codesync[bot]
authored andcommitted
use weak_ptr of NativeAnimatedNodesManager in AnimatedModule (#54564)
Summary: Pull Request resolved: #54564 ## Changelog: [General] [Internal] - use weak_ptr of NativeAnimatedNodesManager in AnimatedModule - so NativeAnimatedNodesManagerProvider is the only owner of NodesManager - Also referencing a nodesManager weak_ptr in the scheduleOnUI call, to prevent AnimatedModule to use a partially destroyed NodesManager Reviewed By: sanjay-io Differential Revision: D87229271 fbshipit-source-id: 619089afcae356fb7a8c3eaf9b101f3ee709bfcc
1 parent 4f20218 commit 27b5ae2

File tree

2 files changed

+87
-82
lines changed

2 files changed

+87
-82
lines changed

packages/react-native/ReactCommon/react/renderer/animated/AnimatedModule.cpp

Lines changed: 85 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ void AnimatedModule::finishOperationBatch(jsi::Runtime& /*rt*/) {
2727
std::swap(preOperations_, preOperations);
2828
std::swap(operations_, operations);
2929

30-
if (nodesManager_) {
30+
if (auto nodesManager = nodesManager_.lock()) {
3131
// TODO: nodesManager_ must exist at all times. But without this check
3232
// AnimatedProps-itest.js fails.
33-
nodesManager_->scheduleOnUI([this,
34-
preOperations = std::move(preOperations),
35-
operations = std::move(operations)]() {
33+
nodesManager->scheduleOnUI([this,
34+
preOperations = std::move(preOperations),
35+
operations = std::move(operations),
36+
nodesManager = nodesManager_]() {
3637
for (auto& preOperation : preOperations) {
37-
executeOperation(preOperation);
38+
executeOperation(preOperation, nodesManager);
3839
}
3940
for (auto& operation : operations) {
40-
executeOperation(operation);
41+
executeOperation(operation, nodesManager);
4142
}
4243
});
4344
}
@@ -50,8 +51,8 @@ void AnimatedModule::createAnimatedNode(
5051
auto configDynamic = dynamicFromValue(rt, jsi::Value(rt, config));
5152
if (auto it = configDynamic.find("disableBatchingForNativeCreate");
5253
it != configDynamic.items().end() && it->second == true) {
53-
if (nodesManager_) {
54-
nodesManager_->createAnimatedNodeAsync(tag, configDynamic);
54+
if (auto nodesManager = nodesManager_.lock()) {
55+
nodesManager->createAnimatedNodeAsync(tag, configDynamic);
5556
}
5657
} else {
5758
operations_.emplace_back(
@@ -220,79 +221,83 @@ void AnimatedModule::queueAndExecuteBatchedOperations(
220221
// TODO(T225953475): missing implementation
221222
}
222223

223-
void AnimatedModule::executeOperation(const Operation& operation) {
224-
if (nodesManager_ == nullptr) {
225-
return;
226-
}
227-
std::visit(
228-
[&](const auto& op) {
229-
using T = std::decay_t<decltype(op)>;
230-
231-
if constexpr (std::is_same_v<T, CreateAnimatedNodeOp>) {
232-
nodesManager_->createAnimatedNode(op.tag, op.config);
233-
} else if constexpr (std::is_same_v<T, GetValueOp>) {
234-
auto animValue = nodesManager_->getValue(op.tag);
235-
if (animValue) {
236-
op.callback.call(animValue.value());
224+
void AnimatedModule::executeOperation(
225+
const Operation& operation,
226+
std::weak_ptr<NativeAnimatedNodesManager> nodesManagerWeak) {
227+
if (auto nodesManager = nodesManagerWeak.lock()) {
228+
std::visit(
229+
[&](const auto& op) {
230+
using T = std::decay_t<decltype(op)>;
231+
232+
if constexpr (std::is_same_v<T, CreateAnimatedNodeOp>) {
233+
nodesManager->createAnimatedNode(op.tag, op.config);
234+
} else if constexpr (std::is_same_v<T, GetValueOp>) {
235+
auto animValue = nodesManager->getValue(op.tag);
236+
if (animValue) {
237+
op.callback.call(animValue.value());
238+
}
239+
} else if constexpr (std::is_same_v<
240+
T,
241+
StartListeningToAnimatedNodeValueOp>) {
242+
nodesManager->startListeningToAnimatedNodeValue(
243+
op.tag, [this, tag = op.tag](double value) {
244+
emitDeviceEvent(
245+
"onAnimatedValueUpdate",
246+
[tag, value](
247+
jsi::Runtime& rt, std::vector<jsi::Value>& args) {
248+
auto arg = jsi::Object(rt);
249+
arg.setProperty(rt, "tag", jsi::Value(tag));
250+
arg.setProperty(rt, "value", jsi::Value(value));
251+
args.emplace_back(rt, arg);
252+
});
253+
});
254+
} else if constexpr (std::is_same_v<
255+
T,
256+
StopListeningToAnimatedNodeValueOp>) {
257+
nodesManager->stopListeningToAnimatedNodeValue(op.tag);
258+
} else if constexpr (std::is_same_v<T, ConnectAnimatedNodesOp>) {
259+
nodesManager->connectAnimatedNodes(op.parentTag, op.childTag);
260+
} else if constexpr (std::is_same_v<T, DisconnectAnimatedNodesOp>) {
261+
nodesManager->disconnectAnimatedNodes(op.parentTag, op.childTag);
262+
} else if constexpr (std::is_same_v<T, StartAnimatingNodeOp>) {
263+
nodesManager->startAnimatingNode(
264+
op.animationId,
265+
op.nodeTag,
266+
std::move(op.config),
267+
std::move(op.endCallback));
268+
} else if constexpr (std::is_same_v<T, StopAnimationOp>) {
269+
nodesManager->stopAnimation(op.animationId, false);
270+
} else if constexpr (std::is_same_v<T, SetAnimatedNodeValueOp>) {
271+
nodesManager->setAnimatedNodeValue(op.nodeTag, op.value);
272+
} else if constexpr (std::is_same_v<T, SetAnimatedNodeOffsetOp>) {
273+
nodesManager->setAnimatedNodeOffset(op.nodeTag, op.offset);
274+
} else if constexpr (std::is_same_v<T, FlattenAnimatedNodeOffsetOp>) {
275+
nodesManager->flattenAnimatedNodeOffset(op.nodeTag);
276+
} else if constexpr (std::is_same_v<T, ExtractAnimatedNodeOffsetOp>) {
277+
nodesManager->extractAnimatedNodeOffsetOp(op.nodeTag);
278+
} else if constexpr (std::is_same_v<T, ConnectAnimatedNodeToViewOp>) {
279+
nodesManager->connectAnimatedNodeToView(op.nodeTag, op.viewTag);
280+
} else if constexpr (std::is_same_v<
281+
T,
282+
DisconnectAnimatedNodeFromViewOp>) {
283+
nodesManager->disconnectAnimatedNodeFromView(
284+
op.nodeTag, op.viewTag);
285+
} else if constexpr (std::is_same_v<T, RestoreDefaultValuesOp>) {
286+
nodesManager->restoreDefaultValues(op.nodeTag);
287+
} else if constexpr (std::is_same_v<T, DropAnimatedNodeOp>) {
288+
nodesManager->dropAnimatedNode(op.tag);
289+
} else if constexpr (std::is_same_v<T, AddAnimatedEventToViewOp>) {
290+
nodesManager->addAnimatedEventToView(
291+
op.viewTag, op.eventName, op.eventMapping);
292+
} else if constexpr (std::is_same_v<
293+
T,
294+
RemoveAnimatedEventFromViewOp>) {
295+
nodesManager->removeAnimatedEventFromView(
296+
op.viewTag, op.eventName, op.animatedNodeTag);
237297
}
238-
} else if constexpr (std::is_same_v<
239-
T,
240-
StartListeningToAnimatedNodeValueOp>) {
241-
nodesManager_->startListeningToAnimatedNodeValue(
242-
op.tag, [this, tag = op.tag](double value) {
243-
emitDeviceEvent(
244-
"onAnimatedValueUpdate",
245-
[tag, value](
246-
jsi::Runtime& rt, std::vector<jsi::Value>& args) {
247-
auto arg = jsi::Object(rt);
248-
arg.setProperty(rt, "tag", jsi::Value(tag));
249-
arg.setProperty(rt, "value", jsi::Value(value));
250-
args.emplace_back(rt, arg);
251-
});
252-
});
253-
} else if constexpr (std::is_same_v<
254-
T,
255-
StopListeningToAnimatedNodeValueOp>) {
256-
nodesManager_->stopListeningToAnimatedNodeValue(op.tag);
257-
} else if constexpr (std::is_same_v<T, ConnectAnimatedNodesOp>) {
258-
nodesManager_->connectAnimatedNodes(op.parentTag, op.childTag);
259-
} else if constexpr (std::is_same_v<T, DisconnectAnimatedNodesOp>) {
260-
nodesManager_->disconnectAnimatedNodes(op.parentTag, op.childTag);
261-
} else if constexpr (std::is_same_v<T, StartAnimatingNodeOp>) {
262-
nodesManager_->startAnimatingNode(
263-
op.animationId,
264-
op.nodeTag,
265-
std::move(op.config),
266-
std::move(op.endCallback));
267-
} else if constexpr (std::is_same_v<T, StopAnimationOp>) {
268-
nodesManager_->stopAnimation(op.animationId, false);
269-
} else if constexpr (std::is_same_v<T, SetAnimatedNodeValueOp>) {
270-
nodesManager_->setAnimatedNodeValue(op.nodeTag, op.value);
271-
} else if constexpr (std::is_same_v<T, SetAnimatedNodeOffsetOp>) {
272-
nodesManager_->setAnimatedNodeOffset(op.nodeTag, op.offset);
273-
} else if constexpr (std::is_same_v<T, FlattenAnimatedNodeOffsetOp>) {
274-
nodesManager_->flattenAnimatedNodeOffset(op.nodeTag);
275-
} else if constexpr (std::is_same_v<T, ExtractAnimatedNodeOffsetOp>) {
276-
nodesManager_->extractAnimatedNodeOffsetOp(op.nodeTag);
277-
} else if constexpr (std::is_same_v<T, ConnectAnimatedNodeToViewOp>) {
278-
nodesManager_->connectAnimatedNodeToView(op.nodeTag, op.viewTag);
279-
} else if constexpr (std::is_same_v<
280-
T,
281-
DisconnectAnimatedNodeFromViewOp>) {
282-
nodesManager_->disconnectAnimatedNodeFromView(op.nodeTag, op.viewTag);
283-
} else if constexpr (std::is_same_v<T, RestoreDefaultValuesOp>) {
284-
nodesManager_->restoreDefaultValues(op.nodeTag);
285-
} else if constexpr (std::is_same_v<T, DropAnimatedNodeOp>) {
286-
nodesManager_->dropAnimatedNode(op.tag);
287-
} else if constexpr (std::is_same_v<T, AddAnimatedEventToViewOp>) {
288-
nodesManager_->addAnimatedEventToView(
289-
op.viewTag, op.eventName, op.eventMapping);
290-
} else if constexpr (std::is_same_v<T, RemoveAnimatedEventFromViewOp>) {
291-
nodesManager_->removeAnimatedEventFromView(
292-
op.viewTag, op.eventName, op.animatedNodeTag);
293-
}
294-
},
295-
operation);
298+
},
299+
operation);
300+
}
296301
}
297302

298303
void AnimatedModule::installJSIBindingsWithRuntime(jsi::Runtime& runtime) {

packages/react-native/ReactCommon/react/renderer/animated/AnimatedModule.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@ class AnimatedModule : public NativeAnimatedModuleCxxSpec<AnimatedModule>, publi
194194

195195
private:
196196
std::shared_ptr<NativeAnimatedNodesManagerProvider> nodesManagerProvider_;
197-
std::shared_ptr<NativeAnimatedNodesManager> nodesManager_;
197+
std::weak_ptr<NativeAnimatedNodesManager> nodesManager_;
198198
std::vector<Operation> preOperations_;
199199
std::vector<Operation> operations_;
200200

201-
void executeOperation(const Operation &operation);
201+
void executeOperation(const Operation &operation, std::weak_ptr<NativeAnimatedNodesManager> nodesManagerWeak);
202202
void installJSIBindingsWithRuntime(jsi::Runtime &runtime) override;
203203
};
204204

0 commit comments

Comments
 (0)