Skip to content

Commit cb02744

Browse files
zeyapfacebook-github-bot
authored andcommitted
Move c++ native animated code to github (#51509)
Summary: Pull Request resolved: #51509 ## Changelog: [Internal] [Added] - Move c++ native animated code to github ⚠️ Note that this is not buildable in OSS yet ⚠️ Reviewed By: sammy-SC, rshest Differential Revision: D75169430 fbshipit-source-id: 499ce209f815474f12007c3c74f81fe0c9ad3f86
1 parent 9b1a8ff commit cb02744

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+4830
-0
lines changed
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "AnimatedModule.h"
9+
10+
#include <glog/logging.h>
11+
#include <jsi/JSIDynamic.h>
12+
13+
namespace facebook::react {
14+
15+
AnimatedModule::AnimatedModule(
16+
std::shared_ptr<CallInvoker> jsInvoker,
17+
std::shared_ptr<NativeAnimatedNodesManagerProvider> nodesManagerProvider)
18+
: NativeAnimatedModuleCxxSpec(jsInvoker),
19+
nodesManagerProvider_(std::move(nodesManagerProvider)) {}
20+
21+
void AnimatedModule::startOperationBatch(jsi::Runtime& /*rt*/) {}
22+
23+
void AnimatedModule::finishOperationBatch(jsi::Runtime& /*rt*/) {
24+
// No mutex needed, operations only added via TurboModule method invocation
25+
std::vector<Operation> preOperations;
26+
std::vector<Operation> operations;
27+
std::swap(preOperations_, preOperations);
28+
std::swap(operations_, operations);
29+
scheduleOperationOnUI([preOperations = std::move(preOperations),
30+
operations = std::move(operations)](
31+
NativeAnimatedNodesManager& nodesManager) {
32+
for (auto& preOperation : preOperations) {
33+
preOperation(nodesManager);
34+
}
35+
36+
for (auto& operation : operations) {
37+
operation(nodesManager);
38+
}
39+
});
40+
}
41+
42+
void AnimatedModule::createAnimatedNode(
43+
jsi::Runtime& rt,
44+
Tag tag,
45+
jsi::Object config) {
46+
auto configDynamic = dynamicFromValue(rt, jsi::Value(rt, config));
47+
addOperation([tag, configDynamic = std::move(configDynamic)](
48+
NativeAnimatedNodesManager& nodesManager) {
49+
nodesManager.createAnimatedNode(tag, configDynamic);
50+
});
51+
}
52+
53+
void AnimatedModule::updateAnimatedNodeConfig(
54+
jsi::Runtime& rt,
55+
Tag tag,
56+
jsi::Object config) {
57+
auto configDynamic = dynamicFromValue(rt, jsi::Value(rt, config));
58+
addOperation([tag, configDynamic = std::move(configDynamic)](
59+
NativeAnimatedNodesManager& nodesManager) {
60+
nodesManager.updateAnimatedNodeConfig(tag, configDynamic);
61+
});
62+
}
63+
64+
void AnimatedModule::getValue(
65+
jsi::Runtime& /*rt*/,
66+
Tag tag,
67+
const AsyncCallback<double>& saveValueCallback) {
68+
addOperation([tag,
69+
saveValueCallback,
70+
weakJsInvoker = std::weak_ptr<CallInvoker>(jsInvoker_)](
71+
NativeAnimatedNodesManager& nodesManager) {
72+
auto animValue = nodesManager.getValue(tag);
73+
auto jsInvoker = weakJsInvoker.lock();
74+
if (animValue && jsInvoker) {
75+
jsInvoker->invokeAsync(
76+
[animValue, saveValueCallback = saveValueCallback]() {
77+
saveValueCallback.call(animValue.value());
78+
});
79+
};
80+
});
81+
}
82+
83+
void AnimatedModule::startListeningToAnimatedNodeValue(
84+
jsi::Runtime& /*rt*/,
85+
Tag tag) {
86+
addOperation([tag, weakThis = weak_from_this()](
87+
NativeAnimatedNodesManager& nodesManager) {
88+
nodesManager.startListeningToAnimatedNodeValue(
89+
tag, [weakThis, tag](double value) {
90+
if (auto strongThis = weakThis.lock()) {
91+
strongThis->emitDeviceEvent(
92+
"onAnimatedValueUpdate",
93+
[tag, value](jsi::Runtime& rt, std::vector<jsi::Value>& args) {
94+
auto arg = jsi::Object(rt);
95+
arg.setProperty(rt, "tag", jsi::Value(tag));
96+
arg.setProperty(rt, "value", jsi::Value(value));
97+
args.emplace_back(rt, arg);
98+
});
99+
}
100+
});
101+
});
102+
}
103+
104+
void AnimatedModule::stopListeningToAnimatedNodeValue(
105+
jsi::Runtime& /*rt*/,
106+
Tag tag) {
107+
addOperation([tag](NativeAnimatedNodesManager& nodesManager) {
108+
nodesManager.stopListeningToAnimatedNodeValue(tag);
109+
});
110+
}
111+
112+
void AnimatedModule::connectAnimatedNodes(
113+
jsi::Runtime& /*rt*/,
114+
Tag parentTag,
115+
Tag childTag) {
116+
addOperation([parentTag, childTag](NativeAnimatedNodesManager& nodesManager) {
117+
nodesManager.connectAnimatedNodes(parentTag, childTag);
118+
});
119+
}
120+
121+
void AnimatedModule::disconnectAnimatedNodes(
122+
jsi::Runtime& /*rt*/,
123+
Tag parentTag,
124+
Tag childTag) {
125+
addOperation([parentTag, childTag](NativeAnimatedNodesManager& nodesManager) {
126+
nodesManager.disconnectAnimatedNodes(parentTag, childTag);
127+
});
128+
}
129+
130+
void AnimatedModule::startAnimatingNode(
131+
jsi::Runtime& rt,
132+
int animationId,
133+
Tag nodeTag,
134+
jsi::Object config,
135+
AnimationEndCallback endCallback) {
136+
auto configDynamic = dynamicFromValue(rt, jsi::Value(rt, config));
137+
addOperation([animationId,
138+
nodeTag,
139+
configDynamic = std::move(configDynamic),
140+
endCallback = std::move(endCallback)](
141+
NativeAnimatedNodesManager& nodesManager) {
142+
nodesManager.startAnimatingNode(
143+
animationId, nodeTag, configDynamic, endCallback);
144+
});
145+
}
146+
147+
void AnimatedModule::stopAnimation(jsi::Runtime& /*rt*/, int animationId) {
148+
addOperation([animationId](NativeAnimatedNodesManager& nodesManager) {
149+
nodesManager.stopAnimation(
150+
animationId, false /* TODO: isTrackingAnimation */);
151+
});
152+
}
153+
154+
void AnimatedModule::setAnimatedNodeValue(
155+
jsi::Runtime& /*rt*/,
156+
Tag nodeTag,
157+
double value) {
158+
addOperation([nodeTag, value](NativeAnimatedNodesManager& nodesManager) {
159+
nodesManager.setAnimatedNodeValue(nodeTag, value);
160+
});
161+
}
162+
163+
void AnimatedModule::setAnimatedNodeOffset(
164+
jsi::Runtime& /*rt*/,
165+
Tag nodeTag,
166+
double offset) {
167+
addOperation([nodeTag, offset](NativeAnimatedNodesManager& nodesManager) {
168+
nodesManager.setAnimatedNodeOffset(nodeTag, offset);
169+
});
170+
}
171+
172+
void AnimatedModule::flattenAnimatedNodeOffset(
173+
jsi::Runtime& /*rt*/,
174+
Tag nodeTag) {
175+
addOperation([nodeTag](NativeAnimatedNodesManager& nodesManager) {
176+
nodesManager.flattenAnimatedNodeOffset(nodeTag);
177+
});
178+
}
179+
180+
void AnimatedModule::extractAnimatedNodeOffset(
181+
jsi::Runtime& /*rt*/,
182+
Tag nodeTag) {
183+
addOperation([nodeTag](NativeAnimatedNodesManager& nodesManager) {
184+
nodesManager.extractAnimatedNodeOffset(nodeTag);
185+
});
186+
}
187+
188+
void AnimatedModule::connectAnimatedNodeToView(
189+
jsi::Runtime& /*rt*/,
190+
Tag nodeTag,
191+
Tag viewTag) {
192+
addOperation([nodeTag, viewTag](NativeAnimatedNodesManager& nodesManager) {
193+
nodesManager.connectAnimatedNodeToView(nodeTag, viewTag);
194+
});
195+
}
196+
197+
void AnimatedModule::disconnectAnimatedNodeFromView(
198+
jsi::Runtime& /*rt*/,
199+
Tag nodeTag,
200+
Tag viewTag) {
201+
addOperation([nodeTag, viewTag](NativeAnimatedNodesManager& nodesManager) {
202+
nodesManager.disconnectAnimatedNodeFromView(nodeTag, viewTag);
203+
});
204+
}
205+
206+
void AnimatedModule::restoreDefaultValues(jsi::Runtime& /*rt*/, Tag nodeTag) {
207+
addOperation(
208+
[nodeTag](NativeAnimatedNodesManager& nodesManager) {
209+
nodesManager.restoreDefaultValues(nodeTag);
210+
},
211+
/* preOperation = */ true);
212+
}
213+
214+
void AnimatedModule::dropAnimatedNode(jsi::Runtime& /*rt*/, Tag tag) {
215+
addOperation([tag](NativeAnimatedNodesManager& nodesManager) {
216+
nodesManager.dropAnimatedNode(tag);
217+
});
218+
}
219+
220+
void AnimatedModule::addAnimatedEventToView(
221+
jsi::Runtime& rt,
222+
Tag viewTag,
223+
const std::string& eventName,
224+
jsi::Object eventMapping) {
225+
auto eventMappingDynamic = dynamicFromValue(rt, jsi::Value(rt, eventMapping));
226+
addOperation([viewTag, eventName, eventMappingDynamic](
227+
NativeAnimatedNodesManager& nodesManager) {
228+
nodesManager.addAnimatedEventToView(
229+
viewTag, eventName, eventMappingDynamic);
230+
});
231+
}
232+
233+
void AnimatedModule::removeAnimatedEventFromView(
234+
jsi::Runtime& /*rt*/,
235+
Tag viewTag,
236+
const std::string& eventName,
237+
Tag animatedNodeTag) {
238+
addOperation([viewTag, eventName, animatedNodeTag](
239+
NativeAnimatedNodesManager& nodesManager) {
240+
nodesManager.removeAnimatedEventFromView(
241+
viewTag, eventName, animatedNodeTag);
242+
});
243+
}
244+
245+
void AnimatedModule::addListener(
246+
jsi::Runtime& rt,
247+
const std::string& eventName) {}
248+
249+
void AnimatedModule::removeListeners(jsi::Runtime& rt, int count) {}
250+
251+
void AnimatedModule::queueAndExecuteBatchedOperations(
252+
jsi::Runtime& rt,
253+
jsi::Array operationsAndArgs) {}
254+
255+
void AnimatedModule::addOperation(Operation&& operation, bool preOperation) {
256+
// No mutex needed, operations only added via TurboModule method invocation
257+
auto& queue = preOperation ? preOperations_ : operations_;
258+
queue.push_back(std::move(operation));
259+
}
260+
261+
void AnimatedModule::installJSIBindingsWithRuntime(jsi::Runtime& runtime) {
262+
if (nodesManagerProvider_) {
263+
nodesManager_ = nodesManagerProvider_->getOrCreate(runtime);
264+
}
265+
}
266+
267+
} // namespace facebook::react
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <FBReactNativeSpec/FBReactNativeSpecJSI.h>
11+
#include <ReactCommon/TurboModuleWithJSIBindings.h>
12+
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
13+
#include <react/renderer/animated/NativeAnimatedNodesManagerProvider.h>
14+
#include <react/renderer/core/ReactPrimitives.h>
15+
#include <memory>
16+
#include <string>
17+
18+
namespace facebook::react {
19+
20+
class AnimatedModule : public NativeAnimatedModuleCxxSpec<AnimatedModule>,
21+
public std::enable_shared_from_this<AnimatedModule>,
22+
public TurboModuleWithJSIBindings {
23+
using Operation =
24+
std::function<void(NativeAnimatedNodesManager& nodesManager)>;
25+
26+
public:
27+
AnimatedModule(
28+
std::shared_ptr<CallInvoker> jsInvoker,
29+
std::shared_ptr<NativeAnimatedNodesManagerProvider> nodesManagerProvider);
30+
31+
void startOperationBatch(jsi::Runtime& rt);
32+
33+
void finishOperationBatch(jsi::Runtime& rt);
34+
35+
void createAnimatedNode(jsi::Runtime& rt, Tag tag, jsi::Object config);
36+
37+
void updateAnimatedNodeConfig(jsi::Runtime& rt, Tag tag, jsi::Object config);
38+
39+
void getValue(
40+
jsi::Runtime& rt,
41+
Tag tag,
42+
const AsyncCallback<double>& saveValueCallback);
43+
44+
void startListeningToAnimatedNodeValue(jsi::Runtime& rt, Tag tag);
45+
46+
void stopListeningToAnimatedNodeValue(jsi::Runtime& rt, Tag tag);
47+
48+
void connectAnimatedNodes(jsi::Runtime& rt, Tag parentTag, Tag childTag);
49+
50+
void disconnectAnimatedNodes(jsi::Runtime& rt, Tag parentTag, Tag childTag);
51+
52+
void startAnimatingNode(
53+
jsi::Runtime& rt,
54+
int animationId,
55+
Tag nodeTag,
56+
jsi::Object config,
57+
AnimationEndCallback endCallback);
58+
59+
void stopAnimation(jsi::Runtime& rt, int animationId);
60+
61+
void setAnimatedNodeValue(jsi::Runtime& rt, Tag nodeTag, double value);
62+
63+
void setAnimatedNodeOffset(jsi::Runtime& rt, Tag nodeTag, double offset);
64+
65+
void flattenAnimatedNodeOffset(jsi::Runtime& rt, Tag nodeTag);
66+
67+
void extractAnimatedNodeOffset(jsi::Runtime& rt, Tag nodeTag);
68+
69+
void connectAnimatedNodeToView(jsi::Runtime& rt, Tag nodeTag, Tag viewTag);
70+
71+
void
72+
disconnectAnimatedNodeFromView(jsi::Runtime& rt, Tag nodeTag, Tag viewTag);
73+
74+
void restoreDefaultValues(jsi::Runtime& rt, Tag nodeTag);
75+
76+
void dropAnimatedNode(jsi::Runtime& rt, Tag tag);
77+
78+
void addAnimatedEventToView(
79+
jsi::Runtime& rt,
80+
Tag viewTag,
81+
const std::string& eventName,
82+
jsi::Object eventMapping);
83+
84+
void removeAnimatedEventFromView(
85+
jsi::Runtime& rt,
86+
Tag viewTag,
87+
const std::string& eventName,
88+
Tag animatedNodeTag);
89+
90+
void addListener(jsi::Runtime& rt, const std::string& eventName);
91+
92+
void removeListeners(jsi::Runtime& rt, int count);
93+
94+
void queueAndExecuteBatchedOperations(
95+
jsi::Runtime& rt,
96+
jsi::Array operationsAndArgs);
97+
98+
void scheduleOperationOnUI(Operation&& fn) {
99+
if (nodesManager_) {
100+
nodesManager_->scheduleOnUI(
101+
[fn = std::move(fn),
102+
weakNodesManager =
103+
std::weak_ptr<NativeAnimatedNodesManager>(nodesManager_)]() {
104+
if (auto nodesManager = weakNodesManager.lock()) {
105+
fn(*nodesManager);
106+
}
107+
});
108+
}
109+
}
110+
111+
protected:
112+
std::shared_ptr<NativeAnimatedNodesManagerProvider> nodesManagerProvider_;
113+
114+
private:
115+
std::shared_ptr<NativeAnimatedNodesManager> nodesManager_;
116+
std::vector<Operation> preOperations_;
117+
std::vector<Operation> operations_;
118+
119+
void addOperation(Operation&& operation, bool preOperation = false);
120+
121+
void installJSIBindingsWithRuntime(jsi::Runtime& runtime) override;
122+
};
123+
124+
} // namespace facebook::react

0 commit comments

Comments
 (0)