Prepare the bridge for C++
Reviewed By: @nicklockwood Differential Revision: D2432291
This commit is contained in:
parent
18a7e363b5
commit
a87ba4ab4c
|
@ -18,7 +18,7 @@
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTModuleData.h"
|
#import "RCTModuleData.h"
|
||||||
#import "RCTModuleMap.h"
|
#import "RCTModuleMap.h"
|
||||||
#import "RCTModuleMethod.h"
|
#import "RCTBridgeMethod.h"
|
||||||
#import "RCTPerformanceLogger.h"
|
#import "RCTPerformanceLogger.h"
|
||||||
#import "RCTPerfStats.h"
|
#import "RCTPerfStats.h"
|
||||||
#import "RCTProfile.h"
|
#import "RCTProfile.h"
|
||||||
|
@ -767,7 +767,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
RCTModuleMethod *method = moduleData.methods[methodID];
|
id<RCTBridgeMethod> method = moduleData.methods[methodID];
|
||||||
if (RCT_DEBUG && !method) {
|
if (RCT_DEBUG && !method) {
|
||||||
RCTLogError(@"Unknown methodID: %zd for module: %zd (%@)", methodID, moduleID, moduleData.name);
|
RCTLogError(@"Unknown methodID: %zd for module: %zd (%@)", methodID, moduleID, moduleData.name);
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -783,12 +783,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RCTProfileEndEvent(0, @"objc_call", @{
|
NSMutableDictionary *args = [method.profileArgs mutableCopy];
|
||||||
@"module": NSStringFromClass(method.moduleClass),
|
[args setValue:method.JSMethodName forKey:@"method"];
|
||||||
@"method": method.JSMethodName,
|
[args setValue:RCTJSONStringify(RCTNullIfNil(params), NULL) forKey:@"args"];
|
||||||
@"selector": NSStringFromSelector(method.selector),
|
|
||||||
@"args": RCTJSONStringify(RCTNullIfNil(params), NULL),
|
RCTProfileEndEvent(0, @"objc_call", args);
|
||||||
});
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@class RCTBridge;
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, RCTFunctionType) {
|
||||||
|
RCTFunctionTypeNormal,
|
||||||
|
RCTFunctionTypePromise,
|
||||||
|
};
|
||||||
|
|
||||||
|
@protocol RCTBridgeMethod <NSObject>
|
||||||
|
|
||||||
|
@property (nonatomic, copy, readonly) NSString *JSMethodName;
|
||||||
|
@property (nonatomic, copy, readonly) NSDictionary *profileArgs;
|
||||||
|
@property (nonatomic, readonly) RCTFunctionType functionType;
|
||||||
|
|
||||||
|
- (void)invokeWithBridge:(RCTBridge *)bridge
|
||||||
|
module:(id)module
|
||||||
|
arguments:(NSArray *)arguments;
|
||||||
|
|
||||||
|
@end
|
|
@ -210,15 +210,21 @@ RCT_EXTERN void RCTRegisterModule(Class); \
|
||||||
#define RCT_EXTERN_REMAP_METHOD(js_name, method) \
|
#define RCT_EXTERN_REMAP_METHOD(js_name, method) \
|
||||||
+ (NSArray *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
|
+ (NSArray *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
|
||||||
return @[@#js_name, @#method]; \
|
return @[@#js_name, @#method]; \
|
||||||
} \
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects methods into JS. Entries in this array are used in addition to any
|
||||||
|
* methods defined using the macros above. This method is called only once,
|
||||||
|
* before registration.
|
||||||
|
*/
|
||||||
|
- (NSArray *)methodsToExport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects constants into JS. These constants are made accessible via
|
* Injects constants into JS. These constants are made accessible via
|
||||||
* NativeModules.ModuleName.X. This method is called when the module is
|
* NativeModules.ModuleName.X. It is only called once for the lifetime of the
|
||||||
* registered by the bridge. It is only called once for the lifetime of the
|
* bridge, so it is not suitable for returning dynamic values, but may be used
|
||||||
* bridge, so it is not suitable for returning dynamic values, but may be
|
* for long-lived values such as session keys, that are regenerated only as
|
||||||
* used for long-lived values such as session keys, that are regenerated only
|
* part of a reload of the entire React application.
|
||||||
* as part of a reload of the entire React application.
|
|
||||||
*/
|
*/
|
||||||
- (NSDictionary *)constantsToExport;
|
- (NSDictionary *)constantsToExport;
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
|
||||||
{
|
{
|
||||||
if (!_methods) {
|
if (!_methods) {
|
||||||
NSMutableArray *moduleMethods = [NSMutableArray new];
|
NSMutableArray *moduleMethods = [NSMutableArray new];
|
||||||
|
|
||||||
|
if ([_instance respondsToSelector:@selector(methodsToExport)]) {
|
||||||
|
[moduleMethods addObjectsFromArray:[_instance methodsToExport]];
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int methodCount;
|
unsigned int methodCount;
|
||||||
Method *methods = class_copyMethodList(object_getClass(_moduleClass), &methodCount);
|
Method *methods = class_copyMethodList(object_getClass(_moduleClass), &methodCount);
|
||||||
|
|
||||||
|
@ -58,7 +63,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
|
||||||
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
|
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
|
||||||
IMP imp = method_getImplementation(method);
|
IMP imp = method_getImplementation(method);
|
||||||
NSArray *entries = ((NSArray *(*)(id, SEL))imp)(_moduleClass, selector);
|
NSArray *entries = ((NSArray *(*)(id, SEL))imp)(_moduleClass, selector);
|
||||||
RCTModuleMethod *moduleMethod =
|
id<RCTBridgeMethod> moduleMethod =
|
||||||
[[RCTModuleMethod alloc] initWithObjCMethodName:entries[1]
|
[[RCTModuleMethod alloc] initWithObjCMethodName:entries[1]
|
||||||
JSMethodName:entries[0]
|
JSMethodName:entries[0]
|
||||||
moduleClass:_moduleClass];
|
moduleClass:_moduleClass];
|
||||||
|
@ -84,7 +89,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableDictionary *methodconfig = [NSMutableDictionary new];
|
NSMutableDictionary *methodconfig = [NSMutableDictionary new];
|
||||||
[self.methods enumerateObjectsUsingBlock:^(RCTModuleMethod *method, NSUInteger idx, __unused BOOL *stop) {
|
[self.methods enumerateObjectsUsingBlock:^(id<RCTBridgeMethod> method, NSUInteger idx, __unused BOOL *stop) {
|
||||||
methodconfig[method.JSMethodName] = @{
|
methodconfig[method.JSMethodName] = @{
|
||||||
@"methodID": @(idx),
|
@"methodID": @(idx),
|
||||||
@"type": method.functionType == RCTFunctionTypePromise ? @"remoteAsync" : @"remote",
|
@"type": method.functionType == RCTFunctionTypePromise ? @"remoteAsync" : @"remote",
|
||||||
|
|
|
@ -9,12 +9,9 @@
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
@class RCTBridge;
|
#import "RCTBridgeMethod.h"
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTFunctionType) {
|
@class RCTBridge;
|
||||||
RCTFunctionTypeNormal,
|
|
||||||
RCTFunctionTypePromise,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTNullability) {
|
typedef NS_ENUM(NSUInteger, RCTNullability) {
|
||||||
RCTNullabilityUnspecified,
|
RCTNullabilityUnspecified,
|
||||||
|
@ -30,9 +27,8 @@ typedef NS_ENUM(NSUInteger, RCTNullability) {
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface RCTModuleMethod : NSObject
|
@interface RCTModuleMethod : NSObject <RCTBridgeMethod>
|
||||||
|
|
||||||
@property (nonatomic, copy, readonly) NSString *JSMethodName;
|
|
||||||
@property (nonatomic, readonly) Class moduleClass;
|
@property (nonatomic, readonly) Class moduleClass;
|
||||||
@property (nonatomic, readonly) SEL selector;
|
@property (nonatomic, readonly) SEL selector;
|
||||||
@property (nonatomic, readonly) RCTFunctionType functionType;
|
@property (nonatomic, readonly) RCTFunctionType functionType;
|
||||||
|
|
|
@ -50,8 +50,11 @@ typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
|
||||||
NSArray *_argumentBlocks;
|
NSArray *_argumentBlocks;
|
||||||
NSString *_objCMethodName;
|
NSString *_objCMethodName;
|
||||||
SEL _selector;
|
SEL _selector;
|
||||||
|
NSDictionary *_profileArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@synthesize JSMethodName = _JSMethodName;
|
||||||
|
|
||||||
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
|
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
|
||||||
id valueOrType, const char *issue)
|
id valueOrType, const char *issue)
|
||||||
{
|
{
|
||||||
|
@ -370,6 +373,19 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||||
return _selector;
|
return _selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)profileArgs
|
||||||
|
{
|
||||||
|
if (_profileArgs) {
|
||||||
|
// This sets _selector
|
||||||
|
[self processMethodSignature];
|
||||||
|
_profileArgs = @{
|
||||||
|
@"module": NSStringFromClass(_moduleClass),
|
||||||
|
@"selector": NSStringFromSelector(_selector),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _profileArgs;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)invokeWithBridge:(RCTBridge *)bridge
|
- (void)invokeWithBridge:(RCTBridge *)bridge
|
||||||
module:(id)module
|
module:(id)module
|
||||||
arguments:(NSArray *)arguments
|
arguments:(NSArray *)arguments
|
||||||
|
|
Loading…
Reference in New Issue