Prepare the bridge for C++

Reviewed By: @nicklockwood

Differential Revision: D2432291
This commit is contained in:
Marc Horowitz 2015-09-18 15:01:21 -07:00 committed by facebook-github-bot-8
parent 18a7e363b5
commit a87ba4ab4c
6 changed files with 74 additions and 23 deletions

View File

@ -18,7 +18,7 @@
#import "RCTLog.h"
#import "RCTModuleData.h"
#import "RCTModuleMap.h"
#import "RCTModuleMethod.h"
#import "RCTBridgeMethod.h"
#import "RCTPerformanceLogger.h"
#import "RCTPerfStats.h"
#import "RCTProfile.h"
@ -767,7 +767,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
return NO;
}
RCTModuleMethod *method = moduleData.methods[methodID];
id<RCTBridgeMethod> method = moduleData.methods[methodID];
if (RCT_DEBUG && !method) {
RCTLogError(@"Unknown methodID: %zd for module: %zd (%@)", methodID, moduleID, moduleData.name);
return NO;
@ -783,12 +783,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
}
}
RCTProfileEndEvent(0, @"objc_call", @{
@"module": NSStringFromClass(method.moduleClass),
@"method": method.JSMethodName,
@"selector": NSStringFromSelector(method.selector),
@"args": RCTJSONStringify(RCTNullIfNil(params), NULL),
});
NSMutableDictionary *args = [method.profileArgs mutableCopy];
[args setValue:method.JSMethodName forKey:@"method"];
[args setValue:RCTJSONStringify(RCTNullIfNil(params), NULL) forKey:@"args"];
RCTProfileEndEvent(0, @"objc_call", args);
return YES;
}

View File

@ -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

View File

@ -210,15 +210,21 @@ RCT_EXTERN void RCTRegisterModule(Class); \
#define RCT_EXTERN_REMAP_METHOD(js_name, method) \
+ (NSArray *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
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
* NativeModules.ModuleName.X. This method is called when the module is
* 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 for long-lived values such as session keys, that are regenerated only
* as part of a reload of the entire React application.
* NativeModules.ModuleName.X. It is only called once for the lifetime of the
* bridge, so it is not suitable for returning dynamic values, but may be used
* for long-lived values such as session keys, that are regenerated only as
* part of a reload of the entire React application.
*/
- (NSDictionary *)constantsToExport;

View File

@ -49,6 +49,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
{
if (!_methods) {
NSMutableArray *moduleMethods = [NSMutableArray new];
if ([_instance respondsToSelector:@selector(methodsToExport)]) {
[moduleMethods addObjectsFromArray:[_instance methodsToExport]];
}
unsigned int methodCount;
Method *methods = class_copyMethodList(object_getClass(_moduleClass), &methodCount);
@ -58,7 +63,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
IMP imp = method_getImplementation(method);
NSArray *entries = ((NSArray *(*)(id, SEL))imp)(_moduleClass, selector);
RCTModuleMethod *moduleMethod =
id<RCTBridgeMethod> moduleMethod =
[[RCTModuleMethod alloc] initWithObjCMethodName:entries[1]
JSMethodName:entries[0]
moduleClass:_moduleClass];
@ -84,7 +89,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
}
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] = @{
@"methodID": @(idx),
@"type": method.functionType == RCTFunctionTypePromise ? @"remoteAsync" : @"remote",

View File

@ -9,12 +9,9 @@
#import <Foundation/Foundation.h>
@class RCTBridge;
#import "RCTBridgeMethod.h"
typedef NS_ENUM(NSUInteger, RCTFunctionType) {
RCTFunctionTypeNormal,
RCTFunctionTypePromise,
};
@class RCTBridge;
typedef NS_ENUM(NSUInteger, RCTNullability) {
RCTNullabilityUnspecified,
@ -30,9 +27,8 @@ typedef NS_ENUM(NSUInteger, RCTNullability) {
@end
@interface RCTModuleMethod : NSObject
@interface RCTModuleMethod : NSObject <RCTBridgeMethod>
@property (nonatomic, copy, readonly) NSString *JSMethodName;
@property (nonatomic, readonly) Class moduleClass;
@property (nonatomic, readonly) SEL selector;
@property (nonatomic, readonly) RCTFunctionType functionType;

View File

@ -50,8 +50,11 @@ typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
NSArray *_argumentBlocks;
NSString *_objCMethodName;
SEL _selector;
NSDictionary *_profileArgs;
}
@synthesize JSMethodName = _JSMethodName;
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
id valueOrType, const char *issue)
{
@ -370,6 +373,19 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
return _selector;
}
- (NSDictionary *)profileArgs
{
if (_profileArgs) {
// This sets _selector
[self processMethodSignature];
_profileArgs = @{
@"module": NSStringFromClass(_moduleClass),
@"selector": NSStringFromSelector(_selector),
};
}
return _profileArgs;
}
- (void)invokeWithBridge:(RCTBridge *)bridge
module:(id)module
arguments:(NSArray *)arguments