/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #import #import #import #import #import #import #import #import #import #import #define RCT_IS_TURBO_MODULE_CLASS(klass) \ ((RCTTurboModuleEnabled() && [(klass) conformsToProtocol:@protocol(RCTTurboModule)])) #define RCT_IS_TURBO_MODULE_INSTANCE(module) RCT_IS_TURBO_MODULE_CLASS([(module) class]) namespace facebook { namespace react { class Instance; typedef std::weak_ptr ( ^RCTRetainJSCallback)(jsi::Function &&callback, jsi::Runtime &runtime, std::shared_ptr jsInvoker); /** * ObjC++ specific TurboModule base class. */ class JSI_EXPORT ObjCTurboModule : public TurboModule { public: // TODO(T65603471): Should we unify this with a Fabric abstraction? struct InitParams { std::string moduleName; id instance; std::shared_ptr jsInvoker; std::shared_ptr nativeInvoker; bool isSyncModule; RCTRetainJSCallback retainJSCallback; }; ObjCTurboModule(const InitParams ¶ms); jsi::Value invokeObjCMethod( jsi::Runtime &runtime, TurboModuleMethodValueKind valueKind, const std::string &methodName, SEL selector, const jsi::Value *args, size_t count); id instance_; std::shared_ptr nativeInvoker_; protected: void setMethodArgConversionSelector(NSString *methodName, int argIndex, NSString *fnName); private: // Does the NativeModule dispatch async methods to the JS thread? const bool isSyncModule_; RCTRetainJSCallback retainJSCallback_; /** * TODO(ramanpreet): * Investigate an optimization that'll let us get rid of this NSMutableDictionary. */ NSMutableDictionary *methodArgConversionSelectors_; NSDictionary *> *methodArgumentTypeNames_; bool isMethodSync(TurboModuleMethodValueKind returnType); BOOL hasMethodArgConversionSelector(NSString *methodName, int argIndex); SEL getMethodArgConversionSelector(NSString *methodName, int argIndex); NSString *getArgumentTypeName(NSString *methodName, int argIndex); NSInvocation *getMethodInvocation( jsi::Runtime &runtime, TurboModuleMethodValueKind returnType, const char *methodName, SEL selector, const jsi::Value *args, size_t count, NSMutableArray *retainedObjectsForInvocation); jsi::Value performMethodInvocation( jsi::Runtime &runtime, TurboModuleMethodValueKind returnType, const char *methodName, NSInvocation *inv, NSMutableArray *retainedObjectsForInvocation); using PromiseInvocationBlock = void (^)(RCTPromiseResolveBlock resolveWrapper, RCTPromiseRejectBlock rejectWrapper); jsi::Value createPromise(jsi::Runtime &runtime, std::string methodName, PromiseInvocationBlock invoke); }; } // namespace react } // namespace facebook @protocol RCTTurboModule - (std::shared_ptr)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params; @end /** * These methods are all implemented by RCTCxxBridge, which subclasses RCTBridge. Hence, they must only be used in * contexts where the concrete class of an RCTBridge instance is RCTCxxBridge. This happens, for example, when * [RCTCxxBridgeDelegate jsExecutorFactoryForBridge:(RCTBridge *)] is invoked by RCTCxxBridge. * * TODO: Consolidate this extension with the one in RCTSurfacePresenter. */ @interface RCTBridge (RCTTurboModule) - (std::shared_ptr)jsCallInvoker; - (std::shared_ptr)decorateNativeCallInvoker: (std::shared_ptr)nativeInvoker; @end