1*5f154df9Saleqsio #include "Shareables.h"
2*5f154df9Saleqsio 
3*5f154df9Saleqsio using namespace facebook;
4*5f154df9Saleqsio 
5*5f154df9Saleqsio namespace reanimated {
6*5f154df9Saleqsio 
CoreFunction(JSRuntimeHelper * runtimeHelper,const jsi::Value & workletValue)7*5f154df9Saleqsio CoreFunction::CoreFunction(
8*5f154df9Saleqsio     JSRuntimeHelper *runtimeHelper,
9*5f154df9Saleqsio     const jsi::Value &workletValue)
10*5f154df9Saleqsio     : runtimeHelper_(runtimeHelper) {
11*5f154df9Saleqsio   jsi::Runtime &rt = *runtimeHelper->rnRuntime();
12*5f154df9Saleqsio   auto workletObject = workletValue.asObject(rt);
13*5f154df9Saleqsio   rnFunction_ = std::make_unique<jsi::Function>(workletObject.asFunction(rt));
14*5f154df9Saleqsio   functionBody_ = workletObject.getPropertyAsObject(rt, "__initData")
15*5f154df9Saleqsio                       .getProperty(rt, "code")
16*5f154df9Saleqsio                       .asString(rt)
17*5f154df9Saleqsio                       .utf8(rt);
18*5f154df9Saleqsio   location_ = "worklet_" +
19*5f154df9Saleqsio       std::to_string(static_cast<uint64_t>(
20*5f154df9Saleqsio           workletObject.getProperty(rt, "__workletHash").getNumber()));
21*5f154df9Saleqsio }
22*5f154df9Saleqsio 
getFunction(jsi::Runtime & rt)23*5f154df9Saleqsio std::unique_ptr<jsi::Function> &CoreFunction::getFunction(jsi::Runtime &rt) {
24*5f154df9Saleqsio   if (runtimeHelper_->isUIRuntime(rt)) {
25*5f154df9Saleqsio     if (uiFunction_ == nullptr) {
26*5f154df9Saleqsio       // maybe need to initialize UI Function
27*5f154df9Saleqsio       // the newline before closing paren is needed because the last line can be
28*5f154df9Saleqsio       // an inline comment (specifically this happens when we attach source maps
29*5f154df9Saleqsio       // at the end) in which case the paren won't be parsed
30*5f154df9Saleqsio       auto codeBuffer = std::make_shared<const jsi::StringBuffer>(
31*5f154df9Saleqsio           "(" + functionBody_ + "\n)");
32*5f154df9Saleqsio       uiFunction_ = std::make_unique<jsi::Function>(
33*5f154df9Saleqsio           rt.evaluateJavaScript(codeBuffer, location_)
34*5f154df9Saleqsio               .asObject(rt)
35*5f154df9Saleqsio               .asFunction(rt));
36*5f154df9Saleqsio     }
37*5f154df9Saleqsio     return uiFunction_;
38*5f154df9Saleqsio   } else {
39*5f154df9Saleqsio     // running on the main RN runtime
40*5f154df9Saleqsio     return rnFunction_;
41*5f154df9Saleqsio   }
42*5f154df9Saleqsio }
43*5f154df9Saleqsio 
extractShareableOrThrow(jsi::Runtime & rt,const jsi::Value & maybeShareableValue,const char * errorMessage)44*5f154df9Saleqsio std::shared_ptr<Shareable> extractShareableOrThrow(
45*5f154df9Saleqsio     jsi::Runtime &rt,
46*5f154df9Saleqsio     const jsi::Value &maybeShareableValue,
47*5f154df9Saleqsio     const char *errorMessage) {
48*5f154df9Saleqsio   if (maybeShareableValue.isObject()) {
49*5f154df9Saleqsio     auto object = maybeShareableValue.asObject(rt);
50*5f154df9Saleqsio     if (object.isHostObject<ShareableJSRef>(rt)) {
51*5f154df9Saleqsio       return object.getHostObject<ShareableJSRef>(rt)->value();
52*5f154df9Saleqsio     }
53*5f154df9Saleqsio   } else if (maybeShareableValue.isUndefined()) {
54*5f154df9Saleqsio     return Shareable::undefined();
55*5f154df9Saleqsio   }
56*5f154df9Saleqsio   throw std::runtime_error(
57*5f154df9Saleqsio       errorMessage != nullptr
58*5f154df9Saleqsio           ? errorMessage
59*5f154df9Saleqsio           : "expecting the object to be of type ShareableJSRef");
60*5f154df9Saleqsio }
61*5f154df9Saleqsio 
~Shareable()62*5f154df9Saleqsio Shareable::~Shareable() {}
63*5f154df9Saleqsio 
ShareableArray(jsi::Runtime & rt,const jsi::Array & array)64*5f154df9Saleqsio ShareableArray::ShareableArray(jsi::Runtime &rt, const jsi::Array &array)
65*5f154df9Saleqsio     : Shareable(ArrayType) {
66*5f154df9Saleqsio   auto size = array.size(rt);
67*5f154df9Saleqsio   data_.reserve(size);
68*5f154df9Saleqsio   for (size_t i = 0; i < size; i++) {
69*5f154df9Saleqsio     data_.push_back(extractShareableOrThrow(rt, array.getValueAtIndex(rt, i)));
70*5f154df9Saleqsio   }
71*5f154df9Saleqsio }
72*5f154df9Saleqsio 
ShareableObject(jsi::Runtime & rt,const jsi::Object & object)73*5f154df9Saleqsio ShareableObject::ShareableObject(jsi::Runtime &rt, const jsi::Object &object)
74*5f154df9Saleqsio     : Shareable(ObjectType) {
75*5f154df9Saleqsio   auto propertyNames = object.getPropertyNames(rt);
76*5f154df9Saleqsio   auto size = propertyNames.size(rt);
77*5f154df9Saleqsio   data_.reserve(size);
78*5f154df9Saleqsio   for (size_t i = 0; i < size; i++) {
79*5f154df9Saleqsio     auto key = propertyNames.getValueAtIndex(rt, i).asString(rt);
80*5f154df9Saleqsio     auto value = extractShareableOrThrow(rt, object.getProperty(rt, key));
81*5f154df9Saleqsio     data_.emplace_back(key.utf8(rt), value);
82*5f154df9Saleqsio   }
83*5f154df9Saleqsio }
84*5f154df9Saleqsio 
undefined()85*5f154df9Saleqsio std::shared_ptr<Shareable> Shareable::undefined() {
86*5f154df9Saleqsio   static auto undefined = std::make_shared<ShareableScalar>();
87*5f154df9Saleqsio   return undefined;
88*5f154df9Saleqsio }
89*5f154df9Saleqsio 
90*5f154df9Saleqsio } /* namespace reanimated */
91