164f5c95fSŁukasz Kosmaty // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 264f5c95fSŁukasz Kosmaty 364f5c95fSŁukasz Kosmaty #pragma once 464f5c95fSŁukasz Kosmaty 564f5c95fSŁukasz Kosmaty #include <fbjni/fbjni.h> 664f5c95fSŁukasz Kosmaty #include <jsi/jsi.h> 764f5c95fSŁukasz Kosmaty #include <react/jni/ReadableNativeArray.h> 864f5c95fSŁukasz Kosmaty #include <jni/JCallback.h> 964f5c95fSŁukasz Kosmaty 10e6ec10dbSŁukasz Kosmaty #include <unordered_map> 1164f5c95fSŁukasz Kosmaty 1264f5c95fSŁukasz Kosmaty #include "MethodMetadata.h" 1364f5c95fSŁukasz Kosmaty #include "JNIFunctionBody.h" 1465a981ddSŁukasz Kosmaty #include "types/ExpectedType.h" 1564f5c95fSŁukasz Kosmaty 1664f5c95fSŁukasz Kosmaty namespace jni = facebook::jni; 1764f5c95fSŁukasz Kosmaty namespace jsi = facebook::jsi; 1864f5c95fSŁukasz Kosmaty namespace react = facebook::react; 1964f5c95fSŁukasz Kosmaty 2064f5c95fSŁukasz Kosmaty namespace expo { 2164f5c95fSŁukasz Kosmaty class JSIInteropModuleRegistry; 2264f5c95fSŁukasz Kosmaty 23cf4fff55SŁukasz Kosmaty class JavaScriptModuleObject; 24cf4fff55SŁukasz Kosmaty 25cf4fff55SŁukasz Kosmaty void decorateObjectWithFunctions( 26cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime, 27cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 28cf4fff55SŁukasz Kosmaty jsi::Object *jsObject, 29cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData 30cf4fff55SŁukasz Kosmaty ); 31cf4fff55SŁukasz Kosmaty 32cf4fff55SŁukasz Kosmaty void decorateObjectWithProperties( 33cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime, 34cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 35cf4fff55SŁukasz Kosmaty jsi::Object *jsObject, 36cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData 37cf4fff55SŁukasz Kosmaty ); 38cf4fff55SŁukasz Kosmaty 39cf4fff55SŁukasz Kosmaty void decorateObjectWithConstants( 40cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime, 41cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 42cf4fff55SŁukasz Kosmaty jsi::Object *jsObject, 43cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData 44cf4fff55SŁukasz Kosmaty ); 45cf4fff55SŁukasz Kosmaty 4664f5c95fSŁukasz Kosmaty /** 4764f5c95fSŁukasz Kosmaty * A CPP part of the module. 4864f5c95fSŁukasz Kosmaty * 4964f5c95fSŁukasz Kosmaty * Right now objects of this class are stored by the ModuleHolder to ensure they will live 5064f5c95fSŁukasz Kosmaty * as long as the RN context. 5164f5c95fSŁukasz Kosmaty */ 5264f5c95fSŁukasz Kosmaty class JavaScriptModuleObject : public jni::HybridClass<JavaScriptModuleObject> { 5364f5c95fSŁukasz Kosmaty public: 5464f5c95fSŁukasz Kosmaty static auto constexpr 5564f5c95fSŁukasz Kosmaty kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptModuleObject;"; 5664f5c95fSŁukasz Kosmaty static auto constexpr TAG = "JavaScriptModuleObject"; 5764f5c95fSŁukasz Kosmaty 5864f5c95fSŁukasz Kosmaty static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis); 5964f5c95fSŁukasz Kosmaty 6064f5c95fSŁukasz Kosmaty static void registerNatives(); 6164f5c95fSŁukasz Kosmaty 6264f5c95fSŁukasz Kosmaty /** 6364f5c95fSŁukasz Kosmaty * Pointer to the module registry interop. 6464f5c95fSŁukasz Kosmaty */ 6564f5c95fSŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry; 6664f5c95fSŁukasz Kosmaty 6764f5c95fSŁukasz Kosmaty /** 6864f5c95fSŁukasz Kosmaty * Returns a cached instance of jsi::Object representing this module. 6964f5c95fSŁukasz Kosmaty * @param runtime 7064f5c95fSŁukasz Kosmaty * @return Wrapped instance of JavaScriptModuleObject::HostObject 7164f5c95fSŁukasz Kosmaty */ 7264f5c95fSŁukasz Kosmaty std::shared_ptr<jsi::Object> getJSIObject(jsi::Runtime &runtime); 7364f5c95fSŁukasz Kosmaty 7464f5c95fSŁukasz Kosmaty /** 75a764be12SŁukasz Kosmaty * Exports constants that will be assigned to the underlying HostObject. 76a764be12SŁukasz Kosmaty */ 77a764be12SŁukasz Kosmaty void exportConstants(jni::alias_ref<react::NativeMap::javaobject> constants); 78a764be12SŁukasz Kosmaty 79a764be12SŁukasz Kosmaty /** 8064f5c95fSŁukasz Kosmaty * Registers a sync function. 8164f5c95fSŁukasz Kosmaty * That function can be called via the `JavaScriptModuleObject.callSyncMethod` method. 8264f5c95fSŁukasz Kosmaty */ 8364f5c95fSŁukasz Kosmaty void registerSyncFunction( 8464f5c95fSŁukasz Kosmaty jni::alias_ref<jstring> name, 85cf4fff55SŁukasz Kosmaty jboolean takesOwner, 8664f5c95fSŁukasz Kosmaty jint args, 8765a981ddSŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes, 8847a022e6SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> body 8964f5c95fSŁukasz Kosmaty ); 9064f5c95fSŁukasz Kosmaty 9164f5c95fSŁukasz Kosmaty /** 9264f5c95fSŁukasz Kosmaty * Registers a async function. 9364f5c95fSŁukasz Kosmaty * That function can be called via the `JavaScriptModuleObject.callAsyncMethod` method. 9464f5c95fSŁukasz Kosmaty */ 9564f5c95fSŁukasz Kosmaty void registerAsyncFunction( 9664f5c95fSŁukasz Kosmaty jni::alias_ref<jstring> name, 97cf4fff55SŁukasz Kosmaty jboolean takesOwner, 9864f5c95fSŁukasz Kosmaty jint args, 9965a981ddSŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes, 10047a022e6SŁukasz Kosmaty jni::alias_ref<JNIAsyncFunctionBody::javaobject> body 10147a022e6SŁukasz Kosmaty ); 10247a022e6SŁukasz Kosmaty 103cf4fff55SŁukasz Kosmaty void registerClass( 104cf4fff55SŁukasz Kosmaty jni::alias_ref<jstring> name, 105ecb7f347SŁukasz Kosmaty jni::alias_ref<JavaScriptModuleObject::javaobject> classObject, 106ecb7f347SŁukasz Kosmaty jboolean takesOwner, 107ecb7f347SŁukasz Kosmaty jint args, 108ecb7f347SŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes, 109ecb7f347SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> body 110cf4fff55SŁukasz Kosmaty ); 111cf4fff55SŁukasz Kosmaty 1123852c14fSŁukasz Kosmaty void registerViewPrototype( 1133852c14fSŁukasz Kosmaty jni::alias_ref<JavaScriptModuleObject::javaobject> viewPrototype 1143852c14fSŁukasz Kosmaty ); 1153852c14fSŁukasz Kosmaty 11647a022e6SŁukasz Kosmaty /** 11747a022e6SŁukasz Kosmaty * Registers a property 11847a022e6SŁukasz Kosmaty * @param name of the property 11947a022e6SŁukasz Kosmaty * @param desiredType of the setter argument 12047a022e6SŁukasz Kosmaty * @param getter body for the get method - can be nullptr 12147a022e6SŁukasz Kosmaty * @param setter body for the set method - can be nullptr 12247a022e6SŁukasz Kosmaty */ 12347a022e6SŁukasz Kosmaty void registerProperty( 12447a022e6SŁukasz Kosmaty jni::alias_ref<jstring> name, 125*b1cbccf5SŁukasz Kosmaty jboolean getterTakesOwner, 126*b1cbccf5SŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> getterExpectedArgsTypes, 12747a022e6SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> getter, 128*b1cbccf5SŁukasz Kosmaty jboolean setterTakesOwner, 129*b1cbccf5SŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> setterExpectedArgsTypes, 13047a022e6SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> setter 13164f5c95fSŁukasz Kosmaty ); 13264f5c95fSŁukasz Kosmaty 13364f5c95fSŁukasz Kosmaty private: 134aaf1c10dSKudo Chien explicit JavaScriptModuleObject(jni::alias_ref<jhybridobject> jThis); 135aaf1c10dSKudo Chien 136aaf1c10dSKudo Chien private: 13764f5c95fSŁukasz Kosmaty friend HybridBase; 138cf4fff55SŁukasz Kosmaty 139cf4fff55SŁukasz Kosmaty friend void decorateObjectWithFunctions( 140cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime, 141cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 142cf4fff55SŁukasz Kosmaty jsi::Object *jsObject, 143cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData 144cf4fff55SŁukasz Kosmaty ); 145cf4fff55SŁukasz Kosmaty 146cf4fff55SŁukasz Kosmaty friend void decorateObjectWithProperties( 147cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime, 148cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 149cf4fff55SŁukasz Kosmaty jsi::Object *jsObject, 150cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData 151cf4fff55SŁukasz Kosmaty ); 152cf4fff55SŁukasz Kosmaty 153cf4fff55SŁukasz Kosmaty friend void decorateObjectWithConstants( 154cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime, 155cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 156cf4fff55SŁukasz Kosmaty jsi::Object *jsObject, 157cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData 158cf4fff55SŁukasz Kosmaty ); 159cf4fff55SŁukasz Kosmaty 16064f5c95fSŁukasz Kosmaty /** 161b627df43SŁukasz Kosmaty * A reference to the `jsi::Object`. 16264f5c95fSŁukasz Kosmaty * Simple we cached that value to return the same object each time. 163cb63a94cSŁukasz Kosmaty * It's a weak reference because the JS runtime holds the actual object. 164cb63a94cSŁukasz Kosmaty * Doing that allows the runtime to deallocate jsi::Object if it's not needed anymore. 16564f5c95fSŁukasz Kosmaty */ 166cb63a94cSŁukasz Kosmaty std::weak_ptr<jsi::Object> jsiObject; 16764f5c95fSŁukasz Kosmaty jni::global_ref<JavaScriptModuleObject::javaobject> javaPart_; 16864f5c95fSŁukasz Kosmaty 16964f5c95fSŁukasz Kosmaty /** 17064f5c95fSŁukasz Kosmaty * Metadata map that stores information about all available methods on this module. 17164f5c95fSŁukasz Kosmaty */ 172e6ec10dbSŁukasz Kosmaty std::unordered_map<std::string, MethodMetadata> methodsMetadata; 17364f5c95fSŁukasz Kosmaty 174a764be12SŁukasz Kosmaty /** 175a764be12SŁukasz Kosmaty * A constants map. 176a764be12SŁukasz Kosmaty */ 177e6ec10dbSŁukasz Kosmaty std::unordered_map<std::string, folly::dynamic> constants; 178a764be12SŁukasz Kosmaty 17947a022e6SŁukasz Kosmaty /** 18047a022e6SŁukasz Kosmaty * A registry of properties 18147a022e6SŁukasz Kosmaty * The first MethodMetadata points to the getter and the second one to the setter. 18247a022e6SŁukasz Kosmaty */ 18347a022e6SŁukasz Kosmaty std::map<std::string, std::pair<MethodMetadata, MethodMetadata>> properties; 18447a022e6SŁukasz Kosmaty 185ecb7f347SŁukasz Kosmaty std::map< 186ecb7f347SŁukasz Kosmaty std::string, 187ecb7f347SŁukasz Kosmaty std::pair<jni::global_ref<JavaScriptModuleObject::javaobject>, MethodMetadata> 188ecb7f347SŁukasz Kosmaty > classes; 1893852c14fSŁukasz Kosmaty 1903852c14fSŁukasz Kosmaty jni::global_ref<JavaScriptModuleObject::javaobject> viewPrototype; 19164f5c95fSŁukasz Kosmaty }; 19264f5c95fSŁukasz Kosmaty } // namespace expo 193