1 #include "AnimatedSensorModule.h"
2 
3 #include <memory>
4 #include <utility>
5 
6 #include "Shareables.h"
7 
8 namespace reanimated {
9 
AnimatedSensorModule(const PlatformDepMethodsHolder & platformDepMethodsHolder)10 AnimatedSensorModule::AnimatedSensorModule(
11     const PlatformDepMethodsHolder &platformDepMethodsHolder)
12     : platformRegisterSensorFunction_(platformDepMethodsHolder.registerSensor),
13       platformUnregisterSensorFunction_(
14           platformDepMethodsHolder.unregisterSensor) {}
15 
~AnimatedSensorModule()16 AnimatedSensorModule::~AnimatedSensorModule() {
17   assert(sensorsIds_.empty());
18 }
19 
registerSensor(jsi::Runtime & rt,const std::shared_ptr<JSRuntimeHelper> & runtimeHelper,const jsi::Value & sensorTypeValue,const jsi::Value & interval,const jsi::Value & iosReferenceFrame,const jsi::Value & sensorDataHandler)20 jsi::Value AnimatedSensorModule::registerSensor(
21     jsi::Runtime &rt,
22     const std::shared_ptr<JSRuntimeHelper> &runtimeHelper,
23     const jsi::Value &sensorTypeValue,
24     const jsi::Value &interval,
25     const jsi::Value &iosReferenceFrame,
26     const jsi::Value &sensorDataHandler) {
27   SensorType sensorType = static_cast<SensorType>(sensorTypeValue.asNumber());
28 
29   auto shareableHandler = extractShareableOrThrow(rt, sensorDataHandler);
30 
31   int sensorId = platformRegisterSensorFunction_(
32       sensorType,
33       interval.asNumber(),
34       iosReferenceFrame.asNumber(),
35       [sensorType,
36        shareableHandler,
37        weakRuntimeHelper = std::weak_ptr<JSRuntimeHelper>(runtimeHelper)](
38           double newValues[], int orientationDegrees) {
39         auto runtimeHelper = weakRuntimeHelper.lock();
40         if (runtimeHelper == nullptr || runtimeHelper->uiRuntimeDestroyed) {
41           return;
42         }
43 
44         auto &rt = *runtimeHelper->uiRuntime();
45         auto handler = shareableHandler->getJSValue(rt);
46         if (sensorType == SensorType::ROTATION_VECTOR) {
47           jsi::Object value(rt);
48           // TODO: timestamp should be provided by the platform implementation
49           // such that the native side has a chance of providing a true event
50           // timestamp
51           value.setProperty(rt, "qx", newValues[0]);
52           value.setProperty(rt, "qy", newValues[1]);
53           value.setProperty(rt, "qz", newValues[2]);
54           value.setProperty(rt, "qw", newValues[3]);
55           value.setProperty(rt, "yaw", newValues[4]);
56           value.setProperty(rt, "pitch", newValues[5]);
57           value.setProperty(rt, "roll", newValues[6]);
58           value.setProperty(rt, "interfaceOrientation", orientationDegrees);
59           runtimeHelper->runOnUIGuarded(handler, value);
60         } else {
61           jsi::Object value(rt);
62           value.setProperty(rt, "x", newValues[0]);
63           value.setProperty(rt, "y", newValues[1]);
64           value.setProperty(rt, "z", newValues[2]);
65           value.setProperty(rt, "interfaceOrientation", orientationDegrees);
66           runtimeHelper->runOnUIGuarded(handler, value);
67         }
68       });
69   if (sensorId != -1) {
70     sensorsIds_.insert(sensorId);
71   }
72   return jsi::Value(sensorId);
73 }
74 
unregisterSensor(const jsi::Value & sensorId)75 void AnimatedSensorModule::unregisterSensor(const jsi::Value &sensorId) {
76   // It is called during sensor hook unmounting
77   sensorsIds_.erase(sensorId.getNumber());
78   platformUnregisterSensorFunction_(sensorId.asNumber());
79 }
80 
unregisterAllSensors()81 void AnimatedSensorModule::unregisterAllSensors() {
82   for (auto sensorId : sensorsIds_) {
83     platformUnregisterSensorFunction_(sensorId);
84   }
85   sensorsIds_.clear();
86 }
87 
88 } // namespace reanimated
89