1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #include "JavaScriptObject.h" 4 #include "JavaScriptValue.h" 5 #include "JavaScriptRuntime.h" 6 #include "JSITypeConverter.h" 7 8 namespace expo { 9 void JavaScriptObject::registerNatives() { 10 registerHybrid({ 11 makeNativeMethod("hasProperty", JavaScriptObject::jniHasProperty), 12 makeNativeMethod("getProperty", JavaScriptObject::jniGetProperty), 13 makeNativeMethod("getPropertyNames", JavaScriptObject::jniGetPropertyNames), 14 makeNativeMethod("setBoolProperty", JavaScriptObject::setProperty<bool>), 15 makeNativeMethod("setDoubleProperty", JavaScriptObject::setProperty<double>), 16 makeNativeMethod("setStringProperty", 17 JavaScriptObject::setProperty<jni::alias_ref<jstring>>), 18 makeNativeMethod("setJSValueProperty", 19 JavaScriptObject::setProperty<jni::alias_ref<JavaScriptValue::javaobject>>), 20 makeNativeMethod("setJSObjectProperty", 21 JavaScriptObject::setProperty<jni::alias_ref<JavaScriptObject::javaobject>>), 22 makeNativeMethod("unsetProperty", JavaScriptObject::unsetProperty), 23 }); 24 } 25 26 JavaScriptObject::JavaScriptObject( 27 std::weak_ptr<JavaScriptRuntime> runtime, 28 std::shared_ptr<jsi::Object> jsObject 29 ) : runtimeHolder(std::move(runtime)), jsObject(std::move(jsObject)) { 30 assert(runtimeHolder.lock() != nullptr); 31 } 32 33 std::shared_ptr<jsi::Object> JavaScriptObject::get() { 34 return jsObject; 35 } 36 37 bool JavaScriptObject::hasProperty(const std::string &name) { 38 auto runtime = runtimeHolder.lock(); 39 assert(runtime != nullptr); 40 return jsObject->hasProperty(*runtime->get(), name.c_str()); 41 } 42 43 jsi::Value JavaScriptObject::getProperty(const std::string &name) { 44 auto runtime = runtimeHolder.lock(); 45 assert(runtime != nullptr); 46 return jsObject->getProperty(*runtime->get(), name.c_str()); 47 } 48 49 bool JavaScriptObject::jniHasProperty(jni::alias_ref<jstring> name) { 50 return hasProperty(name->toStdString()); 51 } 52 53 jni::local_ref<JavaScriptValue::javaobject> JavaScriptObject::jniGetProperty( 54 jni::alias_ref<jstring> name 55 ) { 56 auto result = std::make_shared<jsi::Value>(getProperty(name->toStdString())); 57 return JavaScriptValue::newObjectCxxArgs(runtimeHolder, result); 58 } 59 60 std::vector<std::string> JavaScriptObject::getPropertyNames() { 61 auto runtime = runtimeHolder.lock(); 62 assert(runtime != nullptr); 63 64 jsi::Array properties = jsObject->getPropertyNames(*runtime->get()); 65 auto size = properties.size(*runtime->get()); 66 67 std::vector<std::string> names(size); 68 for (size_t i = 0; i < size; i++) { 69 auto propertyName = properties 70 .getValueAtIndex(*runtime->get(), i) 71 .asString(*runtime->get()) 72 .utf8(*runtime->get()); 73 names[i] = propertyName; 74 } 75 76 return names; 77 } 78 79 jni::local_ref<jni::JArrayClass<jstring>> JavaScriptObject::jniGetPropertyNames() { 80 std::vector<std::string> cResult = getPropertyNames(); 81 auto paredResult = jni::JArrayClass<jstring>::newArray(cResult.size()); 82 for (size_t i = 0; i < cResult.size(); i++) { 83 paredResult->setElement(i, jni::make_jstring(cResult[i]).get()); 84 } 85 86 return paredResult; 87 } 88 89 void JavaScriptObject::setProperty(const std::string &name, jsi::Value value) { 90 auto runtime = runtimeHolder.lock(); 91 assert(runtime != nullptr); 92 jsObject->setProperty(*runtime->get(), name.c_str(), value); 93 } 94 95 void JavaScriptObject::unsetProperty(jni::alias_ref<jstring> name) { 96 auto runtime = runtimeHolder.lock(); 97 assert(runtime != nullptr); 98 auto cName = name->toStdString(); 99 jsObject->setProperty( 100 *runtime->get(), 101 cName.c_str(), 102 jsi::Value::undefined() 103 ); 104 } 105 } // namespace expo 106