1*4440fb50SKudo Chien #include "NativeReanimatedModule.h"
2*4440fb50SKudo Chien
3*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
4*4440fb50SKudo Chien #include <react/renderer/core/TraitCast.h>
5*4440fb50SKudo Chien #include <react/renderer/uimanager/UIManagerBinding.h>
6*4440fb50SKudo Chien #include <react/renderer/uimanager/primitives.h>
7*4440fb50SKudo Chien #endif
8*4440fb50SKudo Chien
9*4440fb50SKudo Chien #include <functional>
10*4440fb50SKudo Chien #include <memory>
11*4440fb50SKudo Chien #include <thread>
12*4440fb50SKudo Chien #include <unordered_map>
13*4440fb50SKudo Chien
14*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
15*4440fb50SKudo Chien #include "FabricUtils.h"
16*4440fb50SKudo Chien #include "NewestShadowNodesRegistry.h"
17*4440fb50SKudo Chien #include "ReanimatedUIManagerBinding.h"
18*4440fb50SKudo Chien #include "ShadowTreeCloner.h"
19*4440fb50SKudo Chien #endif
20*4440fb50SKudo Chien
21*4440fb50SKudo Chien #include "EventHandlerRegistry.h"
22*4440fb50SKudo Chien #include "FeaturesConfig.h"
23*4440fb50SKudo Chien #include "ReanimatedHiddenHeaders.h"
24*4440fb50SKudo Chien #include "RuntimeDecorator.h"
25*4440fb50SKudo Chien #include "Shareables.h"
26*4440fb50SKudo Chien #include "WorkletEventHandler.h"
27*4440fb50SKudo Chien
28*4440fb50SKudo Chien using namespace facebook;
29*4440fb50SKudo Chien
30*4440fb50SKudo Chien namespace reanimated {
31*4440fb50SKudo Chien
NativeReanimatedModule(const std::shared_ptr<CallInvoker> & jsInvoker,const std::shared_ptr<Scheduler> & scheduler,const std::shared_ptr<jsi::Runtime> & rt,const std::shared_ptr<ErrorHandler> & errorHandler,PlatformDepMethodsHolder platformDepMethodsHolder)32*4440fb50SKudo Chien NativeReanimatedModule::NativeReanimatedModule(
33*4440fb50SKudo Chien const std::shared_ptr<CallInvoker> &jsInvoker,
34*4440fb50SKudo Chien const std::shared_ptr<Scheduler> &scheduler,
35*4440fb50SKudo Chien const std::shared_ptr<jsi::Runtime> &rt,
36*4440fb50SKudo Chien const std::shared_ptr<ErrorHandler> &errorHandler,
37*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
38*4440fb50SKudo Chien // nothing
39*4440fb50SKudo Chien #else
40*4440fb50SKudo Chien std::function<jsi::Value(jsi::Runtime &, const int, const jsi::String &)>
41*4440fb50SKudo Chien propObtainer,
42*4440fb50SKudo Chien #endif
43*4440fb50SKudo Chien PlatformDepMethodsHolder platformDepMethodsHolder)
44*4440fb50SKudo Chien : NativeReanimatedModuleSpec(jsInvoker),
45*4440fb50SKudo Chien RuntimeManager(rt, errorHandler, scheduler, RuntimeType::UI),
46*4440fb50SKudo Chien eventHandlerRegistry(std::make_unique<EventHandlerRegistry>()),
47*4440fb50SKudo Chien requestRender(platformDepMethodsHolder.requestRender),
48*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
49*4440fb50SKudo Chien // nothing
50*4440fb50SKudo Chien #else
51*4440fb50SKudo Chien propObtainer(propObtainer),
52*4440fb50SKudo Chien #endif
53*4440fb50SKudo Chien animatedSensorModule(platformDepMethodsHolder),
54*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
55*4440fb50SKudo Chien synchronouslyUpdateUIPropsFunction(
56*4440fb50SKudo Chien platformDepMethodsHolder.synchronouslyUpdateUIPropsFunction)
57*4440fb50SKudo Chien #else
58*4440fb50SKudo Chien configurePropsPlatformFunction(
59*4440fb50SKudo Chien platformDepMethodsHolder.configurePropsFunction)
60*4440fb50SKudo Chien #endif
61*4440fb50SKudo Chien {
62*4440fb50SKudo Chien auto requestAnimationFrame = [=](jsi::Runtime &rt, const jsi::Value &fn) {
63*4440fb50SKudo Chien auto jsFunction = std::make_shared<jsi::Value>(rt, fn);
64*4440fb50SKudo Chien frameCallbacks.push_back([=](double timestamp) {
65*4440fb50SKudo Chien runtimeHelper->runOnUIGuarded(*jsFunction, jsi::Value(timestamp));
66*4440fb50SKudo Chien });
67*4440fb50SKudo Chien maybeRequestRender();
68*4440fb50SKudo Chien };
69*4440fb50SKudo Chien
70*4440fb50SKudo Chien auto scheduleOnJS = [this](
71*4440fb50SKudo Chien jsi::Runtime &rt,
72*4440fb50SKudo Chien const jsi::Value &remoteFun,
73*4440fb50SKudo Chien const jsi::Value &argsValue) {
74*4440fb50SKudo Chien auto shareableRemoteFun = extractShareableOrThrow<ShareableRemoteFunction>(
75*4440fb50SKudo Chien rt,
76*4440fb50SKudo Chien remoteFun,
77*4440fb50SKudo Chien "Incompatible object passed to scheduleOnJS. It is only allowed to schedule functions defined on the React Native JS runtime this way.");
78*4440fb50SKudo Chien auto shareableArgs = argsValue.isUndefined()
79*4440fb50SKudo Chien ? nullptr
80*4440fb50SKudo Chien : extractShareableOrThrow(rt, argsValue);
81*4440fb50SKudo Chien auto jsRuntime = this->runtimeHelper->rnRuntime();
82*4440fb50SKudo Chien this->scheduler->scheduleOnJS([=] {
83*4440fb50SKudo Chien jsi::Runtime &rt = *jsRuntime;
84*4440fb50SKudo Chien auto remoteFun = shareableRemoteFun->getJSValue(rt);
85*4440fb50SKudo Chien if (shareableArgs == nullptr) {
86*4440fb50SKudo Chien // fast path for remote function w/o arguments
87*4440fb50SKudo Chien remoteFun.asObject(rt).asFunction(rt).call(rt);
88*4440fb50SKudo Chien } else {
89*4440fb50SKudo Chien auto argsArray = shareableArgs->getJSValue(rt).asObject(rt).asArray(rt);
90*4440fb50SKudo Chien auto argsSize = argsArray.size(rt);
91*4440fb50SKudo Chien // number of arguments is typically relatively small so it is ok to
92*4440fb50SKudo Chien // to use VLAs here, hence disabling the lint rule
93*4440fb50SKudo Chien jsi::Value args[argsSize]; // NOLINT(runtime/arrays)
94*4440fb50SKudo Chien for (size_t i = 0; i < argsSize; i++) {
95*4440fb50SKudo Chien args[i] = argsArray.getValueAtIndex(rt, i);
96*4440fb50SKudo Chien }
97*4440fb50SKudo Chien remoteFun.asObject(rt).asFunction(rt).call(rt, args, argsSize);
98*4440fb50SKudo Chien }
99*4440fb50SKudo Chien });
100*4440fb50SKudo Chien };
101*4440fb50SKudo Chien
102*4440fb50SKudo Chien auto makeShareableClone = [this](jsi::Runtime &rt, const jsi::Value &value) {
103*4440fb50SKudo Chien return this->makeShareableClone(rt, value, jsi::Value::undefined());
104*4440fb50SKudo Chien };
105*4440fb50SKudo Chien
106*4440fb50SKudo Chien auto updateDataSynchronously =
107*4440fb50SKudo Chien [this](
108*4440fb50SKudo Chien jsi::Runtime &rt,
109*4440fb50SKudo Chien const jsi::Value &synchronizedDataHolderRef,
110*4440fb50SKudo Chien const jsi::Value &newData) {
111*4440fb50SKudo Chien return this->updateDataSynchronously(
112*4440fb50SKudo Chien rt, synchronizedDataHolderRef, newData);
113*4440fb50SKudo Chien };
114*4440fb50SKudo Chien
115*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
116*4440fb50SKudo Chien auto updateProps = [this](
117*4440fb50SKudo Chien jsi::Runtime &rt,
118*4440fb50SKudo Chien const jsi::Value &shadowNodeValue,
119*4440fb50SKudo Chien const jsi::Value &props) {
120*4440fb50SKudo Chien this->updateProps(rt, shadowNodeValue, props);
121*4440fb50SKudo Chien };
122*4440fb50SKudo Chien
123*4440fb50SKudo Chien auto removeShadowNodeFromRegistry =
124*4440fb50SKudo Chien [this](jsi::Runtime &rt, const jsi::Value &tag) {
125*4440fb50SKudo Chien this->removeShadowNodeFromRegistry(rt, tag);
126*4440fb50SKudo Chien };
127*4440fb50SKudo Chien
128*4440fb50SKudo Chien auto measure = [this](jsi::Runtime &rt, const jsi::Value &shadowNodeValue) {
129*4440fb50SKudo Chien return this->measure(rt, shadowNodeValue);
130*4440fb50SKudo Chien };
131*4440fb50SKudo Chien
132*4440fb50SKudo Chien auto dispatchCommand = [this](
133*4440fb50SKudo Chien jsi::Runtime &rt,
134*4440fb50SKudo Chien const jsi::Value &shadowNodeValue,
135*4440fb50SKudo Chien const jsi::Value &commandNameValue,
136*4440fb50SKudo Chien const jsi::Value &argsValue) {
137*4440fb50SKudo Chien this->dispatchCommand(rt, shadowNodeValue, commandNameValue, argsValue);
138*4440fb50SKudo Chien };
139*4440fb50SKudo Chien #endif
140*4440fb50SKudo Chien
141*4440fb50SKudo Chien RuntimeDecorator::decorateUIRuntime(
142*4440fb50SKudo Chien *runtime,
143*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
144*4440fb50SKudo Chien updateProps,
145*4440fb50SKudo Chien measure,
146*4440fb50SKudo Chien removeShadowNodeFromRegistry,
147*4440fb50SKudo Chien dispatchCommand,
148*4440fb50SKudo Chien #else
149*4440fb50SKudo Chien platformDepMethodsHolder.updatePropsFunction,
150*4440fb50SKudo Chien platformDepMethodsHolder.measureFunction,
151*4440fb50SKudo Chien platformDepMethodsHolder.scrollToFunction,
152*4440fb50SKudo Chien #endif
153*4440fb50SKudo Chien requestAnimationFrame,
154*4440fb50SKudo Chien scheduleOnJS,
155*4440fb50SKudo Chien makeShareableClone,
156*4440fb50SKudo Chien updateDataSynchronously,
157*4440fb50SKudo Chien platformDepMethodsHolder.getCurrentTime,
158*4440fb50SKudo Chien platformDepMethodsHolder.setGestureStateFunction,
159*4440fb50SKudo Chien platformDepMethodsHolder.progressLayoutAnimation,
160*4440fb50SKudo Chien platformDepMethodsHolder.endLayoutAnimation,
161*4440fb50SKudo Chien platformDepMethodsHolder.maybeFlushUIUpdatesQueueFunction);
162*4440fb50SKudo Chien onRenderCallback = [this](double timestampMs) {
163*4440fb50SKudo Chien this->renderRequested = false;
164*4440fb50SKudo Chien this->onRender(timestampMs);
165*4440fb50SKudo Chien };
166*4440fb50SKudo Chien
167*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
168*4440fb50SKudo Chien // nothing
169*4440fb50SKudo Chien #else
170*4440fb50SKudo Chien updatePropsFunction = platformDepMethodsHolder.updatePropsFunction;
171*4440fb50SKudo Chien #endif
172*4440fb50SKudo Chien subscribeForKeyboardEventsFunction =
173*4440fb50SKudo Chien platformDepMethodsHolder.subscribeForKeyboardEvents;
174*4440fb50SKudo Chien unsubscribeFromKeyboardEventsFunction =
175*4440fb50SKudo Chien platformDepMethodsHolder.unsubscribeFromKeyboardEvents;
176*4440fb50SKudo Chien }
177*4440fb50SKudo Chien
installCoreFunctions(jsi::Runtime & rt,const jsi::Value & callGuard,const jsi::Value & valueUnpacker)178*4440fb50SKudo Chien void NativeReanimatedModule::installCoreFunctions(
179*4440fb50SKudo Chien jsi::Runtime &rt,
180*4440fb50SKudo Chien const jsi::Value &callGuard,
181*4440fb50SKudo Chien const jsi::Value &valueUnpacker) {
182*4440fb50SKudo Chien if (!runtimeHelper) {
183*4440fb50SKudo Chien // initialize runtimeHelper here if not already present. We expect only one
184*4440fb50SKudo Chien // instace of the helper to exists.
185*4440fb50SKudo Chien runtimeHelper =
186*4440fb50SKudo Chien std::make_shared<JSRuntimeHelper>(&rt, this->runtime.get(), scheduler);
187*4440fb50SKudo Chien }
188*4440fb50SKudo Chien runtimeHelper->callGuard =
189*4440fb50SKudo Chien std::make_unique<CoreFunction>(runtimeHelper.get(), callGuard);
190*4440fb50SKudo Chien runtimeHelper->valueUnpacker =
191*4440fb50SKudo Chien std::make_unique<CoreFunction>(runtimeHelper.get(), valueUnpacker);
192*4440fb50SKudo Chien }
193*4440fb50SKudo Chien
~NativeReanimatedModule()194*4440fb50SKudo Chien NativeReanimatedModule::~NativeReanimatedModule() {
195*4440fb50SKudo Chien if (runtimeHelper) {
196*4440fb50SKudo Chien runtimeHelper->callGuard = nullptr;
197*4440fb50SKudo Chien runtimeHelper->valueUnpacker = nullptr;
198*4440fb50SKudo Chien // event handler registry and frame callbacks store some JSI values from UI
199*4440fb50SKudo Chien // runtime, so they have to go away before we tear down the runtime
200*4440fb50SKudo Chien eventHandlerRegistry.reset();
201*4440fb50SKudo Chien frameCallbacks.clear();
202*4440fb50SKudo Chien runtime.reset();
203*4440fb50SKudo Chien // make sure uiRuntimeDestroyed is set after the runtime is deallocated
204*4440fb50SKudo Chien runtimeHelper->uiRuntimeDestroyed = true;
205*4440fb50SKudo Chien }
206*4440fb50SKudo Chien }
207*4440fb50SKudo Chien
scheduleOnUI(jsi::Runtime & rt,const jsi::Value & worklet)208*4440fb50SKudo Chien void NativeReanimatedModule::scheduleOnUI(
209*4440fb50SKudo Chien jsi::Runtime &rt,
210*4440fb50SKudo Chien const jsi::Value &worklet) {
211*4440fb50SKudo Chien auto shareableWorklet = extractShareableOrThrow(rt, worklet);
212*4440fb50SKudo Chien assert(
213*4440fb50SKudo Chien shareableWorklet->valueType() == Shareable::WorkletType &&
214*4440fb50SKudo Chien "only worklets can be scheduled to run on UI");
215*4440fb50SKudo Chien scheduler->scheduleOnUI([=] {
216*4440fb50SKudo Chien jsi::Runtime &rt = *runtimeHelper->uiRuntime();
217*4440fb50SKudo Chien auto workletValue = shareableWorklet->getJSValue(rt);
218*4440fb50SKudo Chien runtimeHelper->runOnUIGuarded(workletValue);
219*4440fb50SKudo Chien });
220*4440fb50SKudo Chien }
221*4440fb50SKudo Chien
makeSynchronizedDataHolder(jsi::Runtime & rt,const jsi::Value & initialShareable)222*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::makeSynchronizedDataHolder(
223*4440fb50SKudo Chien jsi::Runtime &rt,
224*4440fb50SKudo Chien const jsi::Value &initialShareable) {
225*4440fb50SKudo Chien auto dataHolder = std::make_shared<ShareableSynchronizedDataHolder>(
226*4440fb50SKudo Chien runtimeHelper, rt, initialShareable);
227*4440fb50SKudo Chien return dataHolder->getJSValue(rt);
228*4440fb50SKudo Chien }
229*4440fb50SKudo Chien
updateDataSynchronously(jsi::Runtime & rt,const jsi::Value & synchronizedDataHolderRef,const jsi::Value & newData)230*4440fb50SKudo Chien void NativeReanimatedModule::updateDataSynchronously(
231*4440fb50SKudo Chien jsi::Runtime &rt,
232*4440fb50SKudo Chien const jsi::Value &synchronizedDataHolderRef,
233*4440fb50SKudo Chien const jsi::Value &newData) {
234*4440fb50SKudo Chien auto dataHolder = extractShareableOrThrow<ShareableSynchronizedDataHolder>(
235*4440fb50SKudo Chien rt, synchronizedDataHolderRef);
236*4440fb50SKudo Chien dataHolder->set(rt, newData);
237*4440fb50SKudo Chien }
238*4440fb50SKudo Chien
getDataSynchronously(jsi::Runtime & rt,const jsi::Value & synchronizedDataHolderRef)239*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::getDataSynchronously(
240*4440fb50SKudo Chien jsi::Runtime &rt,
241*4440fb50SKudo Chien const jsi::Value &synchronizedDataHolderRef) {
242*4440fb50SKudo Chien auto dataHolder = extractShareableOrThrow<ShareableSynchronizedDataHolder>(
243*4440fb50SKudo Chien rt, synchronizedDataHolderRef);
244*4440fb50SKudo Chien return dataHolder->get(rt);
245*4440fb50SKudo Chien }
246*4440fb50SKudo Chien
makeShareableClone(jsi::Runtime & rt,const jsi::Value & value,const jsi::Value & shouldRetainRemote)247*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::makeShareableClone(
248*4440fb50SKudo Chien jsi::Runtime &rt,
249*4440fb50SKudo Chien const jsi::Value &value,
250*4440fb50SKudo Chien const jsi::Value &shouldRetainRemote) {
251*4440fb50SKudo Chien std::shared_ptr<Shareable> shareable;
252*4440fb50SKudo Chien if (value.isObject()) {
253*4440fb50SKudo Chien auto object = value.asObject(rt);
254*4440fb50SKudo Chien if (!object.getProperty(rt, "__workletHash").isUndefined()) {
255*4440fb50SKudo Chien shareable = std::make_shared<ShareableWorklet>(runtimeHelper, rt, object);
256*4440fb50SKudo Chien } else if (!object.getProperty(rt, "__init").isUndefined()) {
257*4440fb50SKudo Chien shareable = std::make_shared<ShareableHandle>(runtimeHelper, rt, object);
258*4440fb50SKudo Chien } else if (object.isFunction(rt)) {
259*4440fb50SKudo Chien auto function = object.asFunction(rt);
260*4440fb50SKudo Chien if (function.isHostFunction(rt)) {
261*4440fb50SKudo Chien shareable =
262*4440fb50SKudo Chien std::make_shared<ShareableHostFunction>(rt, std::move(function));
263*4440fb50SKudo Chien } else {
264*4440fb50SKudo Chien shareable = std::make_shared<ShareableRemoteFunction>(
265*4440fb50SKudo Chien runtimeHelper, rt, std::move(function));
266*4440fb50SKudo Chien }
267*4440fb50SKudo Chien } else if (object.isArray(rt)) {
268*4440fb50SKudo Chien if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
269*4440fb50SKudo Chien shareable = std::make_shared<RetainingShareable<ShareableArray>>(
270*4440fb50SKudo Chien runtimeHelper, rt, object.asArray(rt));
271*4440fb50SKudo Chien } else {
272*4440fb50SKudo Chien shareable = std::make_shared<ShareableArray>(rt, object.asArray(rt));
273*4440fb50SKudo Chien }
274*4440fb50SKudo Chien } else if (object.isHostObject(rt)) {
275*4440fb50SKudo Chien shareable = std::make_shared<ShareableHostObject>(
276*4440fb50SKudo Chien runtimeHelper, rt, object.getHostObject(rt));
277*4440fb50SKudo Chien } else {
278*4440fb50SKudo Chien if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
279*4440fb50SKudo Chien shareable = std::make_shared<RetainingShareable<ShareableObject>>(
280*4440fb50SKudo Chien runtimeHelper, rt, object);
281*4440fb50SKudo Chien } else {
282*4440fb50SKudo Chien shareable = std::make_shared<ShareableObject>(rt, object);
283*4440fb50SKudo Chien }
284*4440fb50SKudo Chien }
285*4440fb50SKudo Chien } else if (value.isString()) {
286*4440fb50SKudo Chien shareable = std::make_shared<ShareableString>(value.asString(rt).utf8(rt));
287*4440fb50SKudo Chien } else if (value.isUndefined()) {
288*4440fb50SKudo Chien shareable = std::make_shared<ShareableScalar>();
289*4440fb50SKudo Chien } else if (value.isNull()) {
290*4440fb50SKudo Chien shareable = std::make_shared<ShareableScalar>(nullptr);
291*4440fb50SKudo Chien } else if (value.isBool()) {
292*4440fb50SKudo Chien shareable = std::make_shared<ShareableScalar>(value.getBool());
293*4440fb50SKudo Chien } else if (value.isNumber()) {
294*4440fb50SKudo Chien shareable = std::make_shared<ShareableScalar>(value.getNumber());
295*4440fb50SKudo Chien } else if (value.isSymbol()) {
296*4440fb50SKudo Chien // TODO: this is only a placeholder implementation, here we replace symbols
297*4440fb50SKudo Chien // with strings in order to make certain objects to be captured. There isn't
298*4440fb50SKudo Chien // yet any usecase for using symbols on the UI runtime so it is fine to keep
299*4440fb50SKudo Chien // it like this for now.
300*4440fb50SKudo Chien shareable =
301*4440fb50SKudo Chien std::make_shared<ShareableString>(value.getSymbol(rt).toString(rt));
302*4440fb50SKudo Chien } else {
303*4440fb50SKudo Chien throw std::runtime_error("attempted to convert an unsupported value type");
304*4440fb50SKudo Chien }
305*4440fb50SKudo Chien return ShareableJSRef::newHostObject(rt, shareable);
306*4440fb50SKudo Chien }
307*4440fb50SKudo Chien
registerEventHandler(jsi::Runtime & rt,const jsi::Value & eventHash,const jsi::Value & worklet)308*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::registerEventHandler(
309*4440fb50SKudo Chien jsi::Runtime &rt,
310*4440fb50SKudo Chien const jsi::Value &eventHash,
311*4440fb50SKudo Chien const jsi::Value &worklet) {
312*4440fb50SKudo Chien static uint64_t EVENT_HANDLER_ID = 1;
313*4440fb50SKudo Chien
314*4440fb50SKudo Chien uint64_t newRegistrationId = EVENT_HANDLER_ID++;
315*4440fb50SKudo Chien auto eventName = eventHash.asString(rt).utf8(rt);
316*4440fb50SKudo Chien auto handlerShareable = extractShareableOrThrow(rt, worklet);
317*4440fb50SKudo Chien
318*4440fb50SKudo Chien scheduler->scheduleOnUI([=] {
319*4440fb50SKudo Chien jsi::Runtime &rt = *runtimeHelper->uiRuntime();
320*4440fb50SKudo Chien auto handlerFunction = handlerShareable->getJSValue(rt);
321*4440fb50SKudo Chien auto handler = std::make_shared<WorkletEventHandler>(
322*4440fb50SKudo Chien runtimeHelper,
323*4440fb50SKudo Chien newRegistrationId,
324*4440fb50SKudo Chien eventName,
325*4440fb50SKudo Chien std::move(handlerFunction));
326*4440fb50SKudo Chien eventHandlerRegistry->registerEventHandler(std::move(handler));
327*4440fb50SKudo Chien });
328*4440fb50SKudo Chien
329*4440fb50SKudo Chien return jsi::Value(static_cast<double>(newRegistrationId));
330*4440fb50SKudo Chien }
331*4440fb50SKudo Chien
unregisterEventHandler(jsi::Runtime & rt,const jsi::Value & registrationId)332*4440fb50SKudo Chien void NativeReanimatedModule::unregisterEventHandler(
333*4440fb50SKudo Chien jsi::Runtime &rt,
334*4440fb50SKudo Chien const jsi::Value ®istrationId) {
335*4440fb50SKudo Chien uint64_t id = registrationId.asNumber();
336*4440fb50SKudo Chien scheduler->scheduleOnUI(
337*4440fb50SKudo Chien [=] { eventHandlerRegistry->unregisterEventHandler(id); });
338*4440fb50SKudo Chien }
339*4440fb50SKudo Chien
getViewProp(jsi::Runtime & rt,const jsi::Value & viewTag,const jsi::Value & propName,const jsi::Value & callback)340*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::getViewProp(
341*4440fb50SKudo Chien jsi::Runtime &rt,
342*4440fb50SKudo Chien const jsi::Value &viewTag,
343*4440fb50SKudo Chien const jsi::Value &propName,
344*4440fb50SKudo Chien const jsi::Value &callback) {
345*4440fb50SKudo Chien const int viewTagInt = static_cast<int>(viewTag.asNumber());
346*4440fb50SKudo Chien std::string propNameStr = propName.asString(rt).utf8(rt);
347*4440fb50SKudo Chien jsi::Function fun = callback.getObject(rt).asFunction(rt);
348*4440fb50SKudo Chien std::shared_ptr<jsi::Function> funPtr =
349*4440fb50SKudo Chien std::make_shared<jsi::Function>(std::move(fun));
350*4440fb50SKudo Chien
351*4440fb50SKudo Chien scheduler->scheduleOnUI([&rt, viewTagInt, funPtr, this, propNameStr]() {
352*4440fb50SKudo Chien const jsi::String propNameValue =
353*4440fb50SKudo Chien jsi::String::createFromUtf8(rt, propNameStr);
354*4440fb50SKudo Chien jsi::Value result = propObtainer(rt, viewTagInt, propNameValue);
355*4440fb50SKudo Chien std::string resultStr = result.asString(rt).utf8(rt);
356*4440fb50SKudo Chien
357*4440fb50SKudo Chien scheduler->scheduleOnJS([&rt, resultStr, funPtr]() {
358*4440fb50SKudo Chien const jsi::String resultValue =
359*4440fb50SKudo Chien jsi::String::createFromUtf8(rt, resultStr);
360*4440fb50SKudo Chien funPtr->call(rt, resultValue);
361*4440fb50SKudo Chien });
362*4440fb50SKudo Chien });
363*4440fb50SKudo Chien
364*4440fb50SKudo Chien return jsi::Value::undefined();
365*4440fb50SKudo Chien }
366*4440fb50SKudo Chien
enableLayoutAnimations(jsi::Runtime & rt,const jsi::Value & config)367*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::enableLayoutAnimations(
368*4440fb50SKudo Chien jsi::Runtime &rt,
369*4440fb50SKudo Chien const jsi::Value &config) {
370*4440fb50SKudo Chien FeaturesConfig::setLayoutAnimationEnabled(config.getBool());
371*4440fb50SKudo Chien return jsi::Value::undefined();
372*4440fb50SKudo Chien }
373*4440fb50SKudo Chien
configureProps(jsi::Runtime & rt,const jsi::Value & uiProps,const jsi::Value & nativeProps)374*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::configureProps(
375*4440fb50SKudo Chien jsi::Runtime &rt,
376*4440fb50SKudo Chien const jsi::Value &uiProps,
377*4440fb50SKudo Chien const jsi::Value &nativeProps) {
378*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
379*4440fb50SKudo Chien jsi::Array array = nativeProps.asObject(rt).asArray(rt);
380*4440fb50SKudo Chien for (int i = 0; i < array.size(rt); ++i) {
381*4440fb50SKudo Chien std::string name = array.getValueAtIndex(rt, i).asString(rt).utf8(rt);
382*4440fb50SKudo Chien nativePropNames_.insert(name);
383*4440fb50SKudo Chien }
384*4440fb50SKudo Chien #else
385*4440fb50SKudo Chien configurePropsPlatformFunction(rt, uiProps, nativeProps);
386*4440fb50SKudo Chien #endif // RCT_NEW_ARCH_ENABLED
387*4440fb50SKudo Chien
388*4440fb50SKudo Chien return jsi::Value::undefined();
389*4440fb50SKudo Chien }
390*4440fb50SKudo Chien
configureLayoutAnimation(jsi::Runtime & rt,const jsi::Value & viewTag,const jsi::Value & type,const jsi::Value & sharedTransitionTag,const jsi::Value & config)391*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::configureLayoutAnimation(
392*4440fb50SKudo Chien jsi::Runtime &rt,
393*4440fb50SKudo Chien const jsi::Value &viewTag,
394*4440fb50SKudo Chien const jsi::Value &type,
395*4440fb50SKudo Chien const jsi::Value &sharedTransitionTag,
396*4440fb50SKudo Chien const jsi::Value &config) {
397*4440fb50SKudo Chien layoutAnimationsManager_.configureAnimation(
398*4440fb50SKudo Chien viewTag.asNumber(),
399*4440fb50SKudo Chien static_cast<LayoutAnimationType>(type.asNumber()),
400*4440fb50SKudo Chien sharedTransitionTag.asString(rt).utf8(rt),
401*4440fb50SKudo Chien extractShareableOrThrow(rt, config));
402*4440fb50SKudo Chien return jsi::Value::undefined();
403*4440fb50SKudo Chien }
404*4440fb50SKudo Chien
onEvent(double eventTimestamp,const std::string & eventName,const jsi::Value & payload)405*4440fb50SKudo Chien void NativeReanimatedModule::onEvent(
406*4440fb50SKudo Chien double eventTimestamp,
407*4440fb50SKudo Chien const std::string &eventName,
408*4440fb50SKudo Chien const jsi::Value &payload) {
409*4440fb50SKudo Chien eventHandlerRegistry->processEvent(
410*4440fb50SKudo Chien *runtime, eventTimestamp, eventName, payload);
411*4440fb50SKudo Chien }
412*4440fb50SKudo Chien
isAnyHandlerWaitingForEvent(std::string eventName)413*4440fb50SKudo Chien bool NativeReanimatedModule::isAnyHandlerWaitingForEvent(
414*4440fb50SKudo Chien std::string eventName) {
415*4440fb50SKudo Chien return eventHandlerRegistry->isAnyHandlerWaitingForEvent(eventName);
416*4440fb50SKudo Chien }
417*4440fb50SKudo Chien
maybeRequestRender()418*4440fb50SKudo Chien void NativeReanimatedModule::maybeRequestRender() {
419*4440fb50SKudo Chien if (!renderRequested) {
420*4440fb50SKudo Chien renderRequested = true;
421*4440fb50SKudo Chien requestRender(onRenderCallback, *this->runtime);
422*4440fb50SKudo Chien }
423*4440fb50SKudo Chien }
424*4440fb50SKudo Chien
onRender(double timestampMs)425*4440fb50SKudo Chien void NativeReanimatedModule::onRender(double timestampMs) {
426*4440fb50SKudo Chien std::vector<FrameCallback> callbacks = frameCallbacks;
427*4440fb50SKudo Chien frameCallbacks.clear();
428*4440fb50SKudo Chien for (auto &callback : callbacks) {
429*4440fb50SKudo Chien callback(timestampMs);
430*4440fb50SKudo Chien }
431*4440fb50SKudo Chien }
432*4440fb50SKudo Chien
registerSensor(jsi::Runtime & rt,const jsi::Value & sensorType,const jsi::Value & interval,const jsi::Value & iosReferenceFrame,const jsi::Value & sensorDataHandler)433*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::registerSensor(
434*4440fb50SKudo Chien jsi::Runtime &rt,
435*4440fb50SKudo Chien const jsi::Value &sensorType,
436*4440fb50SKudo Chien const jsi::Value &interval,
437*4440fb50SKudo Chien const jsi::Value &iosReferenceFrame,
438*4440fb50SKudo Chien const jsi::Value &sensorDataHandler) {
439*4440fb50SKudo Chien return animatedSensorModule.registerSensor(
440*4440fb50SKudo Chien rt,
441*4440fb50SKudo Chien runtimeHelper,
442*4440fb50SKudo Chien sensorType,
443*4440fb50SKudo Chien interval,
444*4440fb50SKudo Chien iosReferenceFrame,
445*4440fb50SKudo Chien sensorDataHandler);
446*4440fb50SKudo Chien }
447*4440fb50SKudo Chien
unregisterSensor(jsi::Runtime & rt,const jsi::Value & sensorId)448*4440fb50SKudo Chien void NativeReanimatedModule::unregisterSensor(
449*4440fb50SKudo Chien jsi::Runtime &rt,
450*4440fb50SKudo Chien const jsi::Value &sensorId) {
451*4440fb50SKudo Chien animatedSensorModule.unregisterSensor(sensorId);
452*4440fb50SKudo Chien }
453*4440fb50SKudo Chien
cleanupSensors()454*4440fb50SKudo Chien void NativeReanimatedModule::cleanupSensors() {
455*4440fb50SKudo Chien animatedSensorModule.unregisterAllSensors();
456*4440fb50SKudo Chien }
457*4440fb50SKudo Chien
458*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
isThereAnyLayoutProp(jsi::Runtime & rt,const jsi::Value & props)459*4440fb50SKudo Chien bool NativeReanimatedModule::isThereAnyLayoutProp(
460*4440fb50SKudo Chien jsi::Runtime &rt,
461*4440fb50SKudo Chien const jsi::Value &props) {
462*4440fb50SKudo Chien const jsi::Array propNames = props.asObject(rt).getPropertyNames(rt);
463*4440fb50SKudo Chien for (size_t i = 0; i < propNames.size(rt); ++i) {
464*4440fb50SKudo Chien const std::string propName =
465*4440fb50SKudo Chien propNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
466*4440fb50SKudo Chien bool isLayoutProp =
467*4440fb50SKudo Chien nativePropNames_.find(propName) != nativePropNames_.end();
468*4440fb50SKudo Chien if (isLayoutProp) {
469*4440fb50SKudo Chien return true;
470*4440fb50SKudo Chien }
471*4440fb50SKudo Chien }
472*4440fb50SKudo Chien return false;
473*4440fb50SKudo Chien }
474*4440fb50SKudo Chien #endif // RCT_NEW_ARCH_ENABLED
475*4440fb50SKudo Chien
handleEvent(const std::string & eventName,const jsi::Value & payload,double currentTime)476*4440fb50SKudo Chien bool NativeReanimatedModule::handleEvent(
477*4440fb50SKudo Chien const std::string &eventName,
478*4440fb50SKudo Chien const jsi::Value &payload,
479*4440fb50SKudo Chien double currentTime) {
480*4440fb50SKudo Chien onEvent(currentTime, eventName, payload);
481*4440fb50SKudo Chien
482*4440fb50SKudo Chien // TODO: return true if Reanimated successfully handled the event
483*4440fb50SKudo Chien // to avoid sending it to JavaScript
484*4440fb50SKudo Chien return false;
485*4440fb50SKudo Chien }
486*4440fb50SKudo Chien
487*4440fb50SKudo Chien #ifdef RCT_NEW_ARCH_ENABLED
handleRawEvent(const RawEvent & rawEvent,double currentTime)488*4440fb50SKudo Chien bool NativeReanimatedModule::handleRawEvent(
489*4440fb50SKudo Chien const RawEvent &rawEvent,
490*4440fb50SKudo Chien double currentTime) {
491*4440fb50SKudo Chien const EventTarget *eventTarget = rawEvent.eventTarget.get();
492*4440fb50SKudo Chien if (eventTarget == nullptr) {
493*4440fb50SKudo Chien // after app reload scrollview is unmounted and its content offset is set to
494*4440fb50SKudo Chien // 0 and view is thrown into recycle pool setting content offset triggers
495*4440fb50SKudo Chien // scroll event eventTarget is null though, because it's unmounting we can
496*4440fb50SKudo Chien // just ignore this event, because it's an event on unmounted component
497*4440fb50SKudo Chien return false;
498*4440fb50SKudo Chien }
499*4440fb50SKudo Chien const std::string &type = rawEvent.type;
500*4440fb50SKudo Chien const ValueFactory &payloadFactory = rawEvent.payloadFactory;
501*4440fb50SKudo Chien
502*4440fb50SKudo Chien int tag = eventTarget->getTag();
503*4440fb50SKudo Chien std::string eventType = type;
504*4440fb50SKudo Chien if (eventType.rfind("top", 0) == 0) {
505*4440fb50SKudo Chien eventType = "on" + eventType.substr(3);
506*4440fb50SKudo Chien }
507*4440fb50SKudo Chien std::string eventName = std::to_string(tag) + eventType;
508*4440fb50SKudo Chien jsi::Runtime &rt = *runtime.get();
509*4440fb50SKudo Chien jsi::Value payload = payloadFactory(rt);
510*4440fb50SKudo Chien
511*4440fb50SKudo Chien auto res = handleEvent(eventName, std::move(payload), currentTime);
512*4440fb50SKudo Chien // TODO: we should call performOperations conditionally if event is handled
513*4440fb50SKudo Chien // (res == true), but for now handleEvent always returns false. Thankfully,
514*4440fb50SKudo Chien // performOperations does not trigger a lot of code if there is nothing to be
515*4440fb50SKudo Chien // done so this is fine for now.
516*4440fb50SKudo Chien performOperations();
517*4440fb50SKudo Chien return res;
518*4440fb50SKudo Chien }
519*4440fb50SKudo Chien
updateProps(jsi::Runtime & rt,const jsi::Value & shadowNodeValue,const jsi::Value & props)520*4440fb50SKudo Chien void NativeReanimatedModule::updateProps(
521*4440fb50SKudo Chien jsi::Runtime &rt,
522*4440fb50SKudo Chien const jsi::Value &shadowNodeValue,
523*4440fb50SKudo Chien const jsi::Value &props) {
524*4440fb50SKudo Chien ShadowNode::Shared shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
525*4440fb50SKudo Chien
526*4440fb50SKudo Chien // TODO: support multiple surfaces
527*4440fb50SKudo Chien surfaceId_ = shadowNode->getSurfaceId();
528*4440fb50SKudo Chien
529*4440fb50SKudo Chien if (isThereAnyLayoutProp(rt, props)) {
530*4440fb50SKudo Chien operationsInBatch_.emplace_back(
531*4440fb50SKudo Chien shadowNode, std::make_unique<jsi::Value>(rt, props));
532*4440fb50SKudo Chien } else {
533*4440fb50SKudo Chien // TODO: batch with layout props changes?
534*4440fb50SKudo Chien Tag tag = shadowNode->getTag();
535*4440fb50SKudo Chien synchronouslyUpdateUIPropsFunction(rt, tag, props);
536*4440fb50SKudo Chien }
537*4440fb50SKudo Chien }
538*4440fb50SKudo Chien
performOperations()539*4440fb50SKudo Chien void NativeReanimatedModule::performOperations() {
540*4440fb50SKudo Chien if (operationsInBatch_.empty()) {
541*4440fb50SKudo Chien return;
542*4440fb50SKudo Chien }
543*4440fb50SKudo Chien
544*4440fb50SKudo Chien auto copiedOperationsQueue = std::move(operationsInBatch_);
545*4440fb50SKudo Chien operationsInBatch_ =
546*4440fb50SKudo Chien std::vector<std::pair<ShadowNode::Shared, std::unique_ptr<jsi::Value>>>();
547*4440fb50SKudo Chien
548*4440fb50SKudo Chien auto copiedTagsToRemove = std::move(tagsToRemove_);
549*4440fb50SKudo Chien tagsToRemove_ = std::vector<Tag>();
550*4440fb50SKudo Chien
551*4440fb50SKudo Chien react_native_assert(uiManager_ != nullptr);
552*4440fb50SKudo Chien const auto &shadowTreeRegistry = uiManager_->getShadowTreeRegistry();
553*4440fb50SKudo Chien jsi::Runtime &rt = *runtime.get();
554*4440fb50SKudo Chien
555*4440fb50SKudo Chien shadowTreeRegistry.visit(surfaceId_, [&](ShadowTree const &shadowTree) {
556*4440fb50SKudo Chien auto lock = newestShadowNodesRegistry_->createLock();
557*4440fb50SKudo Chien
558*4440fb50SKudo Chien shadowTree.commit(
559*4440fb50SKudo Chien [&](RootShadowNode const &oldRootShadowNode) {
560*4440fb50SKudo Chien auto rootNode =
561*4440fb50SKudo Chien oldRootShadowNode.ShadowNode::clone(ShadowNodeFragment{});
562*4440fb50SKudo Chien
563*4440fb50SKudo Chien ShadowTreeCloner shadowTreeCloner{
564*4440fb50SKudo Chien newestShadowNodesRegistry_, uiManager_, surfaceId_};
565*4440fb50SKudo Chien
566*4440fb50SKudo Chien for (const auto &pair : copiedOperationsQueue) {
567*4440fb50SKudo Chien const ShadowNodeFamily &family = pair.first->getFamily();
568*4440fb50SKudo Chien react_native_assert(family.getSurfaceId() == surfaceId_);
569*4440fb50SKudo Chien
570*4440fb50SKudo Chien auto newRootNode = shadowTreeCloner.cloneWithNewProps(
571*4440fb50SKudo Chien rootNode, family, RawProps(rt, *pair.second));
572*4440fb50SKudo Chien
573*4440fb50SKudo Chien if (newRootNode == nullptr) {
574*4440fb50SKudo Chien // this happens when React removed the component but Reanimated
575*4440fb50SKudo Chien // still tries to animate it, let's skip update for this specific
576*4440fb50SKudo Chien // component
577*4440fb50SKudo Chien continue;
578*4440fb50SKudo Chien }
579*4440fb50SKudo Chien rootNode = newRootNode;
580*4440fb50SKudo Chien }
581*4440fb50SKudo Chien
582*4440fb50SKudo Chien // remove ShadowNodes and its ancestors from NewestShadowNodesRegistry
583*4440fb50SKudo Chien for (auto tag : copiedTagsToRemove) {
584*4440fb50SKudo Chien newestShadowNodesRegistry_->remove(tag);
585*4440fb50SKudo Chien }
586*4440fb50SKudo Chien
587*4440fb50SKudo Chien shadowTreeCloner.updateYogaChildren();
588*4440fb50SKudo Chien
589*4440fb50SKudo Chien return std::static_pointer_cast<RootShadowNode>(rootNode);
590*4440fb50SKudo Chien },
591*4440fb50SKudo Chien {/* default commit options */});
592*4440fb50SKudo Chien });
593*4440fb50SKudo Chien }
594*4440fb50SKudo Chien
removeShadowNodeFromRegistry(jsi::Runtime & rt,const jsi::Value & tag)595*4440fb50SKudo Chien void NativeReanimatedModule::removeShadowNodeFromRegistry(
596*4440fb50SKudo Chien jsi::Runtime &rt,
597*4440fb50SKudo Chien const jsi::Value &tag) {
598*4440fb50SKudo Chien tagsToRemove_.push_back(tag.asNumber());
599*4440fb50SKudo Chien }
600*4440fb50SKudo Chien
dispatchCommand(jsi::Runtime & rt,const jsi::Value & shadowNodeValue,const jsi::Value & commandNameValue,const jsi::Value & argsValue)601*4440fb50SKudo Chien void NativeReanimatedModule::dispatchCommand(
602*4440fb50SKudo Chien jsi::Runtime &rt,
603*4440fb50SKudo Chien const jsi::Value &shadowNodeValue,
604*4440fb50SKudo Chien const jsi::Value &commandNameValue,
605*4440fb50SKudo Chien const jsi::Value &argsValue) {
606*4440fb50SKudo Chien ShadowNode::Shared shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
607*4440fb50SKudo Chien std::string commandName = stringFromValue(rt, commandNameValue);
608*4440fb50SKudo Chien folly::dynamic args = commandArgsFromValue(rt, argsValue);
609*4440fb50SKudo Chien uiManager_->dispatchCommand(shadowNode, commandName, args);
610*4440fb50SKudo Chien }
611*4440fb50SKudo Chien
measure(jsi::Runtime & rt,const jsi::Value & shadowNodeValue)612*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::measure(
613*4440fb50SKudo Chien jsi::Runtime &rt,
614*4440fb50SKudo Chien const jsi::Value &shadowNodeValue) {
615*4440fb50SKudo Chien // based on implementation from UIManagerBinding.cpp
616*4440fb50SKudo Chien
617*4440fb50SKudo Chien auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
618*4440fb50SKudo Chien auto layoutMetrics = uiManager_->getRelativeLayoutMetrics(
619*4440fb50SKudo Chien *shadowNode, nullptr, {/* .includeTransform = */ true});
620*4440fb50SKudo Chien
621*4440fb50SKudo Chien if (layoutMetrics == EmptyLayoutMetrics) {
622*4440fb50SKudo Chien // Originally, in this case React Native returns `{0, 0, 0, 0, 0, 0}`, most
623*4440fb50SKudo Chien // likely due to the type of measure callback function which accepts just an
624*4440fb50SKudo Chien // array of numbers (not null). In Reanimated, `measure` returns
625*4440fb50SKudo Chien // `MeasuredDimensions | null`.
626*4440fb50SKudo Chien return jsi::Value::null();
627*4440fb50SKudo Chien }
628*4440fb50SKudo Chien auto newestCloneOfShadowNode =
629*4440fb50SKudo Chien uiManager_->getNewestCloneOfShadowNode(*shadowNode);
630*4440fb50SKudo Chien
631*4440fb50SKudo Chien auto layoutableShadowNode =
632*4440fb50SKudo Chien traitCast<LayoutableShadowNode const *>(newestCloneOfShadowNode.get());
633*4440fb50SKudo Chien facebook::react::Point originRelativeToParent =
634*4440fb50SKudo Chien layoutableShadowNode != nullptr
635*4440fb50SKudo Chien ? layoutableShadowNode->getLayoutMetrics().frame.origin
636*4440fb50SKudo Chien : facebook::react::Point();
637*4440fb50SKudo Chien
638*4440fb50SKudo Chien auto frame = layoutMetrics.frame;
639*4440fb50SKudo Chien
640*4440fb50SKudo Chien jsi::Object result(rt);
641*4440fb50SKudo Chien result.setProperty(
642*4440fb50SKudo Chien rt, "x", jsi::Value(static_cast<double>(originRelativeToParent.x)));
643*4440fb50SKudo Chien result.setProperty(
644*4440fb50SKudo Chien rt, "y", jsi::Value(static_cast<double>(originRelativeToParent.y)));
645*4440fb50SKudo Chien result.setProperty(
646*4440fb50SKudo Chien rt, "width", jsi::Value(static_cast<double>(frame.size.width)));
647*4440fb50SKudo Chien result.setProperty(
648*4440fb50SKudo Chien rt, "height", jsi::Value(static_cast<double>(frame.size.height)));
649*4440fb50SKudo Chien result.setProperty(
650*4440fb50SKudo Chien rt, "pageX", jsi::Value(static_cast<double>(frame.origin.x)));
651*4440fb50SKudo Chien result.setProperty(
652*4440fb50SKudo Chien rt, "pageY", jsi::Value(static_cast<double>(frame.origin.y)));
653*4440fb50SKudo Chien return result;
654*4440fb50SKudo Chien }
655*4440fb50SKudo Chien
setUIManager(std::shared_ptr<UIManager> uiManager)656*4440fb50SKudo Chien void NativeReanimatedModule::setUIManager(
657*4440fb50SKudo Chien std::shared_ptr<UIManager> uiManager) {
658*4440fb50SKudo Chien uiManager_ = uiManager;
659*4440fb50SKudo Chien }
660*4440fb50SKudo Chien
setNewestShadowNodesRegistry(std::shared_ptr<NewestShadowNodesRegistry> newestShadowNodesRegistry)661*4440fb50SKudo Chien void NativeReanimatedModule::setNewestShadowNodesRegistry(
662*4440fb50SKudo Chien std::shared_ptr<NewestShadowNodesRegistry> newestShadowNodesRegistry) {
663*4440fb50SKudo Chien newestShadowNodesRegistry_ = newestShadowNodesRegistry;
664*4440fb50SKudo Chien }
665*4440fb50SKudo Chien #endif // RCT_NEW_ARCH_ENABLED
666*4440fb50SKudo Chien
subscribeForKeyboardEvents(jsi::Runtime & rt,const jsi::Value & handlerWorklet,const jsi::Value & isStatusBarTranslucent)667*4440fb50SKudo Chien jsi::Value NativeReanimatedModule::subscribeForKeyboardEvents(
668*4440fb50SKudo Chien jsi::Runtime &rt,
669*4440fb50SKudo Chien const jsi::Value &handlerWorklet,
670*4440fb50SKudo Chien const jsi::Value &isStatusBarTranslucent) {
671*4440fb50SKudo Chien auto shareableHandler = extractShareableOrThrow(rt, handlerWorklet);
672*4440fb50SKudo Chien return subscribeForKeyboardEventsFunction(
673*4440fb50SKudo Chien [=](int keyboardState, int height) {
674*4440fb50SKudo Chien jsi::Runtime &rt = *runtimeHelper->uiRuntime();
675*4440fb50SKudo Chien auto handler = shareableHandler->getJSValue(rt);
676*4440fb50SKudo Chien runtimeHelper->runOnUIGuarded(
677*4440fb50SKudo Chien handler, jsi::Value(keyboardState), jsi::Value(height));
678*4440fb50SKudo Chien },
679*4440fb50SKudo Chien isStatusBarTranslucent.getBool());
680*4440fb50SKudo Chien }
681*4440fb50SKudo Chien
unsubscribeFromKeyboardEvents(jsi::Runtime & rt,const jsi::Value & listenerId)682*4440fb50SKudo Chien void NativeReanimatedModule::unsubscribeFromKeyboardEvents(
683*4440fb50SKudo Chien jsi::Runtime &rt,
684*4440fb50SKudo Chien const jsi::Value &listenerId) {
685*4440fb50SKudo Chien unsubscribeFromKeyboardEventsFunction(listenerId.asNumber());
686*4440fb50SKudo Chien }
687*4440fb50SKudo Chien
688*4440fb50SKudo Chien } // namespace reanimated
689