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