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