1*753557f6STomasz Sapeta #include "NativeReanimatedModule.h"
2*753557f6STomasz Sapeta #include <functional>
3*753557f6STomasz Sapeta #include <memory>
4*753557f6STomasz Sapeta #include <thread>
5*753557f6STomasz Sapeta #include <unordered_map>
6*753557f6STomasz Sapeta 
7*753557f6STomasz Sapeta #include "EventHandlerRegistry.h"
8*753557f6STomasz Sapeta #include "FeaturesConfig.h"
9*753557f6STomasz Sapeta #include "FrozenObject.h"
10*753557f6STomasz Sapeta #include "JSIStoreValueUser.h"
11*753557f6STomasz Sapeta #include "Mapper.h"
12*753557f6STomasz Sapeta #include "MapperRegistry.h"
13*753557f6STomasz Sapeta #include "MutableValue.h"
14*753557f6STomasz Sapeta #include "ReanimatedHiddenHeaders.h"
15*753557f6STomasz Sapeta #include "RuntimeDecorator.h"
16*753557f6STomasz Sapeta #include "ShareableValue.h"
17*753557f6STomasz Sapeta #include "WorkletEventHandler.h"
18*753557f6STomasz Sapeta 
19*753557f6STomasz Sapeta using namespace ABI47_0_0facebook;
20*753557f6STomasz Sapeta 
21*753557f6STomasz Sapeta namespace ABI47_0_0reanimated {
22*753557f6STomasz Sapeta 
extractMutables(jsi::Runtime & rt,std::shared_ptr<ShareableValue> sv,std::vector<std::shared_ptr<MutableValue>> & res)23*753557f6STomasz Sapeta void extractMutables(
24*753557f6STomasz Sapeta     jsi::Runtime &rt,
25*753557f6STomasz Sapeta     std::shared_ptr<ShareableValue> sv,
26*753557f6STomasz Sapeta     std::vector<std::shared_ptr<MutableValue>> &res) {
27*753557f6STomasz Sapeta   switch (sv->type) {
28*753557f6STomasz Sapeta     case ValueType::MutableValueType: {
29*753557f6STomasz Sapeta       auto &mutableValue = ValueWrapper::asMutableValue(sv->valueContainer);
30*753557f6STomasz Sapeta       res.push_back(mutableValue);
31*753557f6STomasz Sapeta       break;
32*753557f6STomasz Sapeta     }
33*753557f6STomasz Sapeta     case ValueType::FrozenArrayType:
34*753557f6STomasz Sapeta       for (auto &it : ValueWrapper::asFrozenArray(sv->valueContainer)) {
35*753557f6STomasz Sapeta         extractMutables(rt, it, res);
36*753557f6STomasz Sapeta       }
37*753557f6STomasz Sapeta       break;
38*753557f6STomasz Sapeta     case ValueType::RemoteObjectType:
39*753557f6STomasz Sapeta     case ValueType::FrozenObjectType:
40*753557f6STomasz Sapeta       for (auto &it : ValueWrapper::asFrozenObject(sv->valueContainer)->map) {
41*753557f6STomasz Sapeta         extractMutables(rt, it.second, res);
42*753557f6STomasz Sapeta       }
43*753557f6STomasz Sapeta       break;
44*753557f6STomasz Sapeta     default:
45*753557f6STomasz Sapeta       break;
46*753557f6STomasz Sapeta   }
47*753557f6STomasz Sapeta }
48*753557f6STomasz Sapeta 
extractMutablesFromArray(jsi::Runtime & rt,const jsi::Array & array,NativeReanimatedModule * module)49*753557f6STomasz Sapeta std::vector<std::shared_ptr<MutableValue>> extractMutablesFromArray(
50*753557f6STomasz Sapeta     jsi::Runtime &rt,
51*753557f6STomasz Sapeta     const jsi::Array &array,
52*753557f6STomasz Sapeta     NativeReanimatedModule *module) {
53*753557f6STomasz Sapeta   std::vector<std::shared_ptr<MutableValue>> res;
54*753557f6STomasz Sapeta   for (size_t i = 0, size = array.size(rt); i < size; i++) {
55*753557f6STomasz Sapeta     auto shareable =
56*753557f6STomasz Sapeta         ShareableValue::adapt(rt, array.getValueAtIndex(rt, i), module);
57*753557f6STomasz Sapeta     extractMutables(rt, shareable, res);
58*753557f6STomasz Sapeta   }
59*753557f6STomasz Sapeta   return res;
60*753557f6STomasz Sapeta }
61*753557f6STomasz Sapeta 
NativeReanimatedModule(std::shared_ptr<CallInvoker> jsInvoker,std::shared_ptr<Scheduler> scheduler,std::shared_ptr<jsi::Runtime> rt,std::shared_ptr<ErrorHandler> errorHandler,std::function<jsi::Value (jsi::Runtime &,const int,const jsi::String &)> propObtainer,std::shared_ptr<LayoutAnimationsProxy> layoutAnimationsProxy,PlatformDepMethodsHolder platformDepMethodsHolder)62*753557f6STomasz Sapeta NativeReanimatedModule::NativeReanimatedModule(
63*753557f6STomasz Sapeta     std::shared_ptr<CallInvoker> jsInvoker,
64*753557f6STomasz Sapeta     std::shared_ptr<Scheduler> scheduler,
65*753557f6STomasz Sapeta     std::shared_ptr<jsi::Runtime> rt,
66*753557f6STomasz Sapeta     std::shared_ptr<ErrorHandler> errorHandler,
67*753557f6STomasz Sapeta     std::function<jsi::Value(jsi::Runtime &, const int, const jsi::String &)>
68*753557f6STomasz Sapeta         propObtainer,
69*753557f6STomasz Sapeta     std::shared_ptr<LayoutAnimationsProxy> layoutAnimationsProxy,
70*753557f6STomasz Sapeta     PlatformDepMethodsHolder platformDepMethodsHolder)
71*753557f6STomasz Sapeta     : NativeReanimatedModuleSpec(jsInvoker),
72*753557f6STomasz Sapeta       RuntimeManager(rt, errorHandler, scheduler, RuntimeType::UI),
73*753557f6STomasz Sapeta       mapperRegistry(std::make_shared<MapperRegistry>()),
74*753557f6STomasz Sapeta       eventHandlerRegistry(std::make_shared<EventHandlerRegistry>()),
75*753557f6STomasz Sapeta       requestRender(platformDepMethodsHolder.requestRender),
76*753557f6STomasz Sapeta       propObtainer(propObtainer),
77*753557f6STomasz Sapeta       animatedSensorModule(platformDepMethodsHolder, this),
78*753557f6STomasz Sapeta       configurePropsPlatformFunction(
79*753557f6STomasz Sapeta           platformDepMethodsHolder.configurePropsFunction) {
80*753557f6STomasz Sapeta   auto requestAnimationFrame = [=](FrameCallback callback) {
81*753557f6STomasz Sapeta     frameCallbacks.push_back(callback);
82*753557f6STomasz Sapeta     maybeRequestRender();
83*753557f6STomasz Sapeta   };
84*753557f6STomasz Sapeta 
85*753557f6STomasz Sapeta   this->layoutAnimationsProxy = layoutAnimationsProxy;
86*753557f6STomasz Sapeta 
87*753557f6STomasz Sapeta   RuntimeDecorator::decorateUIRuntime(
88*753557f6STomasz Sapeta       *runtime,
89*753557f6STomasz Sapeta       platformDepMethodsHolder.updaterFunction,
90*753557f6STomasz Sapeta       requestAnimationFrame,
91*753557f6STomasz Sapeta       platformDepMethodsHolder.scrollToFunction,
92*753557f6STomasz Sapeta       platformDepMethodsHolder.measuringFunction,
93*753557f6STomasz Sapeta       platformDepMethodsHolder.getCurrentTime,
94*753557f6STomasz Sapeta       platformDepMethodsHolder.registerSensor,
95*753557f6STomasz Sapeta       platformDepMethodsHolder.unregisterSensor,
96*753557f6STomasz Sapeta       platformDepMethodsHolder.setGestureStateFunction,
97*753557f6STomasz Sapeta       layoutAnimationsProxy);
98*753557f6STomasz Sapeta   onRenderCallback = [this](double timestampMs) {
99*753557f6STomasz Sapeta     this->renderRequested = false;
100*753557f6STomasz Sapeta     this->onRender(timestampMs);
101*753557f6STomasz Sapeta   };
102*753557f6STomasz Sapeta   updaterFunction = platformDepMethodsHolder.updaterFunction;
103*753557f6STomasz Sapeta   subscribeForKeyboardEventsFunction =
104*753557f6STomasz Sapeta       platformDepMethodsHolder.subscribeForKeyboardEvents;
105*753557f6STomasz Sapeta   unsubscribeFromKeyboardEventsFunction =
106*753557f6STomasz Sapeta       platformDepMethodsHolder.unsubscribeFromKeyboardEvents;
107*753557f6STomasz Sapeta }
108*753557f6STomasz Sapeta 
installCoreFunctions(jsi::Runtime & rt,const jsi::Value & valueSetter)109*753557f6STomasz Sapeta void NativeReanimatedModule::installCoreFunctions(
110*753557f6STomasz Sapeta     jsi::Runtime &rt,
111*753557f6STomasz Sapeta     const jsi::Value &valueSetter) {
112*753557f6STomasz Sapeta   this->valueSetter = ShareableValue::adapt(rt, valueSetter, this);
113*753557f6STomasz Sapeta }
114*753557f6STomasz Sapeta 
makeShareable(jsi::Runtime & rt,const jsi::Value & value)115*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::makeShareable(
116*753557f6STomasz Sapeta     jsi::Runtime &rt,
117*753557f6STomasz Sapeta     const jsi::Value &value) {
118*753557f6STomasz Sapeta   return ShareableValue::adapt(rt, value, this)->getValue(rt);
119*753557f6STomasz Sapeta }
120*753557f6STomasz Sapeta 
makeMutable(jsi::Runtime & rt,const jsi::Value & value)121*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::makeMutable(
122*753557f6STomasz Sapeta     jsi::Runtime &rt,
123*753557f6STomasz Sapeta     const jsi::Value &value) {
124*753557f6STomasz Sapeta   return ShareableValue::adapt(rt, value, this, ValueType::MutableValueType)
125*753557f6STomasz Sapeta       ->getValue(rt);
126*753557f6STomasz Sapeta }
127*753557f6STomasz Sapeta 
makeRemote(jsi::Runtime & rt,const jsi::Value & value)128*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::makeRemote(
129*753557f6STomasz Sapeta     jsi::Runtime &rt,
130*753557f6STomasz Sapeta     const jsi::Value &value) {
131*753557f6STomasz Sapeta   return ShareableValue::adapt(rt, value, this, ValueType::RemoteObjectType)
132*753557f6STomasz Sapeta       ->getValue(rt);
133*753557f6STomasz Sapeta }
134*753557f6STomasz Sapeta 
startMapper(jsi::Runtime & rt,const jsi::Value & worklet,const jsi::Value & inputs,const jsi::Value & outputs,const jsi::Value & updater,const jsi::Value & viewDescriptors)135*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::startMapper(
136*753557f6STomasz Sapeta     jsi::Runtime &rt,
137*753557f6STomasz Sapeta     const jsi::Value &worklet,
138*753557f6STomasz Sapeta     const jsi::Value &inputs,
139*753557f6STomasz Sapeta     const jsi::Value &outputs,
140*753557f6STomasz Sapeta     const jsi::Value &updater,
141*753557f6STomasz Sapeta     const jsi::Value &viewDescriptors) {
142*753557f6STomasz Sapeta   static unsigned long MAPPER_ID = 1;
143*753557f6STomasz Sapeta 
144*753557f6STomasz Sapeta   unsigned long newMapperId = MAPPER_ID++;
145*753557f6STomasz Sapeta   auto mapperShareable = ShareableValue::adapt(rt, worklet, this);
146*753557f6STomasz Sapeta   auto inputMutables =
147*753557f6STomasz Sapeta       extractMutablesFromArray(rt, inputs.asObject(rt).asArray(rt), this);
148*753557f6STomasz Sapeta   auto outputMutables =
149*753557f6STomasz Sapeta       extractMutablesFromArray(rt, outputs.asObject(rt).asArray(rt), this);
150*753557f6STomasz Sapeta 
151*753557f6STomasz Sapeta   int optimalizationLvl = 0;
152*753557f6STomasz Sapeta   auto optimalization =
153*753557f6STomasz Sapeta       updater.asObject(rt).getProperty(rt, "__optimalization");
154*753557f6STomasz Sapeta   if (optimalization.isNumber()) {
155*753557f6STomasz Sapeta     optimalizationLvl = optimalization.asNumber();
156*753557f6STomasz Sapeta   }
157*753557f6STomasz Sapeta   auto updaterSV = ShareableValue::adapt(rt, updater, this);
158*753557f6STomasz Sapeta   auto viewDescriptorsSV = ShareableValue::adapt(rt, viewDescriptors, this);
159*753557f6STomasz Sapeta 
160*753557f6STomasz Sapeta   scheduler->scheduleOnUI([=] {
161*753557f6STomasz Sapeta     auto mapperFunction =
162*753557f6STomasz Sapeta         mapperShareable->getValue(*runtime).asObject(*runtime).asFunction(
163*753557f6STomasz Sapeta             *runtime);
164*753557f6STomasz Sapeta     std::shared_ptr<jsi::Function> mapperFunctionPointer =
165*753557f6STomasz Sapeta         std::make_shared<jsi::Function>(std::move(mapperFunction));
166*753557f6STomasz Sapeta 
167*753557f6STomasz Sapeta     std::shared_ptr<Mapper> mapperPointer = std::make_shared<Mapper>(
168*753557f6STomasz Sapeta         this,
169*753557f6STomasz Sapeta         newMapperId,
170*753557f6STomasz Sapeta         mapperFunctionPointer,
171*753557f6STomasz Sapeta         inputMutables,
172*753557f6STomasz Sapeta         outputMutables);
173*753557f6STomasz Sapeta     if (optimalizationLvl > 0) {
174*753557f6STomasz Sapeta       mapperPointer->enableFastMode(
175*753557f6STomasz Sapeta           optimalizationLvl, updaterSV, viewDescriptorsSV);
176*753557f6STomasz Sapeta     }
177*753557f6STomasz Sapeta     mapperRegistry->startMapper(mapperPointer);
178*753557f6STomasz Sapeta     maybeRequestRender();
179*753557f6STomasz Sapeta   });
180*753557f6STomasz Sapeta 
181*753557f6STomasz Sapeta   return jsi::Value(static_cast<double>(newMapperId));
182*753557f6STomasz Sapeta }
183*753557f6STomasz Sapeta 
stopMapper(jsi::Runtime & rt,const jsi::Value & mapperId)184*753557f6STomasz Sapeta void NativeReanimatedModule::stopMapper(
185*753557f6STomasz Sapeta     jsi::Runtime &rt,
186*753557f6STomasz Sapeta     const jsi::Value &mapperId) {
187*753557f6STomasz Sapeta   unsigned long id = mapperId.asNumber();
188*753557f6STomasz Sapeta   scheduler->scheduleOnUI([=] {
189*753557f6STomasz Sapeta     mapperRegistry->stopMapper(id);
190*753557f6STomasz Sapeta     maybeRequestRender();
191*753557f6STomasz Sapeta   });
192*753557f6STomasz Sapeta }
193*753557f6STomasz Sapeta 
registerEventHandler(jsi::Runtime & rt,const jsi::Value & eventHash,const jsi::Value & worklet)194*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::registerEventHandler(
195*753557f6STomasz Sapeta     jsi::Runtime &rt,
196*753557f6STomasz Sapeta     const jsi::Value &eventHash,
197*753557f6STomasz Sapeta     const jsi::Value &worklet) {
198*753557f6STomasz Sapeta   static unsigned long EVENT_HANDLER_ID = 1;
199*753557f6STomasz Sapeta 
200*753557f6STomasz Sapeta   unsigned long newRegistrationId = EVENT_HANDLER_ID++;
201*753557f6STomasz Sapeta   auto eventName = eventHash.asString(rt).utf8(rt);
202*753557f6STomasz Sapeta   auto handlerShareable = ShareableValue::adapt(rt, worklet, this);
203*753557f6STomasz Sapeta 
204*753557f6STomasz Sapeta   scheduler->scheduleOnUI([=] {
205*753557f6STomasz Sapeta     auto handlerFunction =
206*753557f6STomasz Sapeta         handlerShareable->getValue(*runtime).asObject(*runtime).asFunction(
207*753557f6STomasz Sapeta             *runtime);
208*753557f6STomasz Sapeta     auto handler = std::make_shared<WorkletEventHandler>(
209*753557f6STomasz Sapeta         newRegistrationId, eventName, std::move(handlerFunction));
210*753557f6STomasz Sapeta     eventHandlerRegistry->registerEventHandler(handler);
211*753557f6STomasz Sapeta   });
212*753557f6STomasz Sapeta 
213*753557f6STomasz Sapeta   return jsi::Value(static_cast<double>(newRegistrationId));
214*753557f6STomasz Sapeta }
215*753557f6STomasz Sapeta 
unregisterEventHandler(jsi::Runtime & rt,const jsi::Value & registrationId)216*753557f6STomasz Sapeta void NativeReanimatedModule::unregisterEventHandler(
217*753557f6STomasz Sapeta     jsi::Runtime &rt,
218*753557f6STomasz Sapeta     const jsi::Value &registrationId) {
219*753557f6STomasz Sapeta   unsigned long id = registrationId.asNumber();
220*753557f6STomasz Sapeta   scheduler->scheduleOnUI(
221*753557f6STomasz Sapeta       [=] { eventHandlerRegistry->unregisterEventHandler(id); });
222*753557f6STomasz Sapeta }
223*753557f6STomasz Sapeta 
getViewProp(jsi::Runtime & rt,const jsi::Value & viewTag,const jsi::Value & propName,const jsi::Value & callback)224*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::getViewProp(
225*753557f6STomasz Sapeta     jsi::Runtime &rt,
226*753557f6STomasz Sapeta     const jsi::Value &viewTag,
227*753557f6STomasz Sapeta     const jsi::Value &propName,
228*753557f6STomasz Sapeta     const jsi::Value &callback) {
229*753557f6STomasz Sapeta   const int viewTagInt = static_cast<int>(viewTag.asNumber());
230*753557f6STomasz Sapeta   std::string propNameStr = propName.asString(rt).utf8(rt);
231*753557f6STomasz Sapeta   jsi::Function fun = callback.getObject(rt).asFunction(rt);
232*753557f6STomasz Sapeta   std::shared_ptr<jsi::Function> funPtr =
233*753557f6STomasz Sapeta       std::make_shared<jsi::Function>(std::move(fun));
234*753557f6STomasz Sapeta 
235*753557f6STomasz Sapeta   scheduler->scheduleOnUI([&rt, viewTagInt, funPtr, this, propNameStr]() {
236*753557f6STomasz Sapeta     const jsi::String propNameValue =
237*753557f6STomasz Sapeta         jsi::String::createFromUtf8(rt, propNameStr);
238*753557f6STomasz Sapeta     jsi::Value result = propObtainer(rt, viewTagInt, propNameValue);
239*753557f6STomasz Sapeta     std::string resultStr = result.asString(rt).utf8(rt);
240*753557f6STomasz Sapeta 
241*753557f6STomasz Sapeta     scheduler->scheduleOnJS([&rt, resultStr, funPtr]() {
242*753557f6STomasz Sapeta       const jsi::String resultValue =
243*753557f6STomasz Sapeta           jsi::String::createFromUtf8(rt, resultStr);
244*753557f6STomasz Sapeta       funPtr->call(rt, resultValue);
245*753557f6STomasz Sapeta     });
246*753557f6STomasz Sapeta   });
247*753557f6STomasz Sapeta 
248*753557f6STomasz Sapeta   return jsi::Value::undefined();
249*753557f6STomasz Sapeta }
250*753557f6STomasz Sapeta 
enableLayoutAnimations(jsi::Runtime & rt,const jsi::Value & config)251*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::enableLayoutAnimations(
252*753557f6STomasz Sapeta     jsi::Runtime &rt,
253*753557f6STomasz Sapeta     const jsi::Value &config) {
254*753557f6STomasz Sapeta   FeaturesConfig::setLayoutAnimationEnabled(config.getBool());
255*753557f6STomasz Sapeta   return jsi::Value::undefined();
256*753557f6STomasz Sapeta }
257*753557f6STomasz Sapeta 
configureProps(jsi::Runtime & rt,const jsi::Value & uiProps,const jsi::Value & nativeProps)258*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::configureProps(
259*753557f6STomasz Sapeta     jsi::Runtime &rt,
260*753557f6STomasz Sapeta     const jsi::Value &uiProps,
261*753557f6STomasz Sapeta     const jsi::Value &nativeProps) {
262*753557f6STomasz Sapeta   configurePropsPlatformFunction(rt, uiProps, nativeProps);
263*753557f6STomasz Sapeta   return jsi::Value::undefined();
264*753557f6STomasz Sapeta }
265*753557f6STomasz Sapeta 
onEvent(std::string eventName,std::string eventAsString)266*753557f6STomasz Sapeta void NativeReanimatedModule::onEvent(
267*753557f6STomasz Sapeta     std::string eventName,
268*753557f6STomasz Sapeta     std::string eventAsString) {
269*753557f6STomasz Sapeta   try {
270*753557f6STomasz Sapeta     eventHandlerRegistry->processEvent(*runtime, eventName, eventAsString);
271*753557f6STomasz Sapeta     mapperRegistry->execute(*runtime);
272*753557f6STomasz Sapeta     if (mapperRegistry->needRunOnRender()) {
273*753557f6STomasz Sapeta       maybeRequestRender();
274*753557f6STomasz Sapeta     }
275*753557f6STomasz Sapeta   } catch (std::exception &e) {
276*753557f6STomasz Sapeta     std::string str = e.what();
277*753557f6STomasz Sapeta     this->errorHandler->setError(str);
278*753557f6STomasz Sapeta     this->errorHandler->raise();
279*753557f6STomasz Sapeta   } catch (...) {
280*753557f6STomasz Sapeta     std::string str = "OnEvent error";
281*753557f6STomasz Sapeta     this->errorHandler->setError(str);
282*753557f6STomasz Sapeta     this->errorHandler->raise();
283*753557f6STomasz Sapeta   }
284*753557f6STomasz Sapeta }
285*753557f6STomasz Sapeta 
isAnyHandlerWaitingForEvent(std::string eventName)286*753557f6STomasz Sapeta bool NativeReanimatedModule::isAnyHandlerWaitingForEvent(
287*753557f6STomasz Sapeta     std::string eventName) {
288*753557f6STomasz Sapeta   return eventHandlerRegistry->isAnyHandlerWaitingForEvent(eventName);
289*753557f6STomasz Sapeta }
290*753557f6STomasz Sapeta 
maybeRequestRender()291*753557f6STomasz Sapeta void NativeReanimatedModule::maybeRequestRender() {
292*753557f6STomasz Sapeta   if (!renderRequested) {
293*753557f6STomasz Sapeta     renderRequested = true;
294*753557f6STomasz Sapeta     requestRender(onRenderCallback, *this->runtime);
295*753557f6STomasz Sapeta   }
296*753557f6STomasz Sapeta }
297*753557f6STomasz Sapeta 
onRender(double timestampMs)298*753557f6STomasz Sapeta void NativeReanimatedModule::onRender(double timestampMs) {
299*753557f6STomasz Sapeta   try {
300*753557f6STomasz Sapeta     std::vector<FrameCallback> callbacks = frameCallbacks;
301*753557f6STomasz Sapeta     frameCallbacks.clear();
302*753557f6STomasz Sapeta     for (auto &callback : callbacks) {
303*753557f6STomasz Sapeta       callback(timestampMs);
304*753557f6STomasz Sapeta     }
305*753557f6STomasz Sapeta     mapperRegistry->execute(*runtime);
306*753557f6STomasz Sapeta 
307*753557f6STomasz Sapeta     if (mapperRegistry->needRunOnRender()) {
308*753557f6STomasz Sapeta       maybeRequestRender();
309*753557f6STomasz Sapeta     }
310*753557f6STomasz Sapeta   } catch (std::exception &e) {
311*753557f6STomasz Sapeta     std::string str = e.what();
312*753557f6STomasz Sapeta     this->errorHandler->setError(str);
313*753557f6STomasz Sapeta     this->errorHandler->raise();
314*753557f6STomasz Sapeta   } catch (...) {
315*753557f6STomasz Sapeta     std::string str = "OnRender error";
316*753557f6STomasz Sapeta     this->errorHandler->setError(str);
317*753557f6STomasz Sapeta     this->errorHandler->raise();
318*753557f6STomasz Sapeta   }
319*753557f6STomasz Sapeta }
320*753557f6STomasz Sapeta 
registerSensor(jsi::Runtime & rt,const jsi::Value & sensorType,const jsi::Value & interval,const jsi::Value & sensorDataContainer)321*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::registerSensor(
322*753557f6STomasz Sapeta     jsi::Runtime &rt,
323*753557f6STomasz Sapeta     const jsi::Value &sensorType,
324*753557f6STomasz Sapeta     const jsi::Value &interval,
325*753557f6STomasz Sapeta     const jsi::Value &sensorDataContainer) {
326*753557f6STomasz Sapeta   return animatedSensorModule.registerSensor(
327*753557f6STomasz Sapeta       rt, sensorType, interval, sensorDataContainer);
328*753557f6STomasz Sapeta }
329*753557f6STomasz Sapeta 
unregisterSensor(jsi::Runtime & rt,const jsi::Value & sensorId)330*753557f6STomasz Sapeta void NativeReanimatedModule::unregisterSensor(
331*753557f6STomasz Sapeta     jsi::Runtime &rt,
332*753557f6STomasz Sapeta     const jsi::Value &sensorId) {
333*753557f6STomasz Sapeta   animatedSensorModule.unregisterSensor(sensorId);
334*753557f6STomasz Sapeta }
335*753557f6STomasz Sapeta 
subscribeForKeyboardEvents(jsi::Runtime & rt,const jsi::Value & keyboardEventContainer)336*753557f6STomasz Sapeta jsi::Value NativeReanimatedModule::subscribeForKeyboardEvents(
337*753557f6STomasz Sapeta     jsi::Runtime &rt,
338*753557f6STomasz Sapeta     const jsi::Value &keyboardEventContainer) {
339*753557f6STomasz Sapeta   jsi::Object keyboardEventObj = keyboardEventContainer.getObject(rt);
340*753557f6STomasz Sapeta   std::unordered_map<std::string, std::shared_ptr<ShareableValue>>
341*753557f6STomasz Sapeta       sharedProperties;
342*753557f6STomasz Sapeta   std::shared_ptr<ShareableValue> keyboardStateShared = ShareableValue::adapt(
343*753557f6STomasz Sapeta       rt, keyboardEventObj.getProperty(rt, "state"), this);
344*753557f6STomasz Sapeta   std::shared_ptr<ShareableValue> heightShared = ShareableValue::adapt(
345*753557f6STomasz Sapeta       rt, keyboardEventObj.getProperty(rt, "height"), this);
346*753557f6STomasz Sapeta 
347*753557f6STomasz Sapeta   auto keyboardEventDataUpdater =
348*753557f6STomasz Sapeta       [this, &rt, keyboardStateShared, heightShared](
349*753557f6STomasz Sapeta           int keyboardState, int height) {
350*753557f6STomasz Sapeta         auto &keyboardStateValue =
351*753557f6STomasz Sapeta             ValueWrapper::asMutableValue(keyboardStateShared->valueContainer);
352*753557f6STomasz Sapeta         keyboardStateValue->setValue(rt, jsi::Value(keyboardState));
353*753557f6STomasz Sapeta 
354*753557f6STomasz Sapeta         auto &heightMutableValue =
355*753557f6STomasz Sapeta             ValueWrapper::asMutableValue(heightShared->valueContainer);
356*753557f6STomasz Sapeta         heightMutableValue->setValue(rt, jsi::Value(height));
357*753557f6STomasz Sapeta 
358*753557f6STomasz Sapeta         this->mapperRegistry->execute(*this->runtime);
359*753557f6STomasz Sapeta       };
360*753557f6STomasz Sapeta 
361*753557f6STomasz Sapeta   return subscribeForKeyboardEventsFunction(keyboardEventDataUpdater);
362*753557f6STomasz Sapeta }
363*753557f6STomasz Sapeta 
unsubscribeFromKeyboardEvents(jsi::Runtime & rt,const jsi::Value & listenerId)364*753557f6STomasz Sapeta void NativeReanimatedModule::unsubscribeFromKeyboardEvents(
365*753557f6STomasz Sapeta     jsi::Runtime &rt,
366*753557f6STomasz Sapeta     const jsi::Value &listenerId) {
367*753557f6STomasz Sapeta   unsubscribeFromKeyboardEventsFunction(listenerId.asNumber());
368*753557f6STomasz Sapeta }
369*753557f6STomasz Sapeta 
370*753557f6STomasz Sapeta } // namespace reanimated
371