mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-30 05:55:48 +08:00
Bring back D2570057 (previously backed out) + fixes
Reviewed By: nicklockwood Differential Revision: D2590604 fb-gh-sync-id: 63a0e0c6afda740f22aacb3f469d411f236fa16b
This commit is contained in:
committed by
facebook-github-bot-7
parent
89f1e6732e
commit
40f513aa71
@@ -136,19 +136,25 @@ _Pragma("clang diagnostic pop")
|
|||||||
NSString *injectedStuff;
|
NSString *injectedStuff;
|
||||||
RUN_RUNLOOP_WHILE(!(injectedStuff = executor.injectedStuff[@"__fbBatchedBridgeConfig"]));
|
RUN_RUNLOOP_WHILE(!(injectedStuff = executor.injectedStuff[@"__fbBatchedBridgeConfig"]));
|
||||||
|
|
||||||
NSDictionary *moduleConfig = RCTJSONParse(injectedStuff, NULL);
|
__block NSNumber *testModuleID = nil;
|
||||||
NSDictionary *remoteModuleConfig = moduleConfig[@"remoteModuleConfig"];
|
__block NSDictionary *testConstants = nil;
|
||||||
NSDictionary *testModuleConfig = remoteModuleConfig[@"TestModule"];
|
__block NSNumber *testMethodID = nil;
|
||||||
NSDictionary *constants = testModuleConfig[@"constants"];
|
|
||||||
NSDictionary *methods = testModuleConfig[@"methods"];
|
NSArray *remoteModuleConfig = RCTJSONParse(injectedStuff, NULL)[@"remoteModuleConfig"];
|
||||||
|
[remoteModuleConfig enumerateObjectsUsingBlock:^(id moduleConfig, NSUInteger i, BOOL *stop) {
|
||||||
|
if ([moduleConfig isKindOfClass:[NSArray class]] && [moduleConfig[0] isEqualToString:@"TestModule"]) {
|
||||||
|
testModuleID = @(i);
|
||||||
|
testConstants = moduleConfig[1];
|
||||||
|
testMethodID = @([moduleConfig[2] indexOfObject:@"testMethod"]);
|
||||||
|
*stop = YES;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
XCTAssertNotNil(moduleConfig);
|
|
||||||
XCTAssertNotNil(remoteModuleConfig);
|
XCTAssertNotNil(remoteModuleConfig);
|
||||||
XCTAssertNotNil(testModuleConfig);
|
XCTAssertNotNil(testModuleID);
|
||||||
XCTAssertNotNil(constants);
|
XCTAssertNotNil(testConstants);
|
||||||
XCTAssertEqualObjects(constants[@"eleventyMillion"], @42);
|
XCTAssertEqualObjects(testConstants[@"eleventyMillion"], @42);
|
||||||
XCTAssertNotNil(methods);
|
XCTAssertNotNil(testMethodID);
|
||||||
XCTAssertNotNil(methods[@"testMethod"]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testCallNativeMethod
|
- (void)testCallNativeMethod
|
||||||
@@ -158,13 +164,19 @@ _Pragma("clang diagnostic pop")
|
|||||||
NSString *injectedStuff;
|
NSString *injectedStuff;
|
||||||
RUN_RUNLOOP_WHILE(!(injectedStuff = executor.injectedStuff[@"__fbBatchedBridgeConfig"]));
|
RUN_RUNLOOP_WHILE(!(injectedStuff = executor.injectedStuff[@"__fbBatchedBridgeConfig"]));
|
||||||
|
|
||||||
NSDictionary *moduleConfig = RCTJSONParse(injectedStuff, NULL);
|
__block NSNumber *testModuleID = nil;
|
||||||
NSDictionary *remoteModuleConfig = moduleConfig[@"remoteModuleConfig"];
|
__block NSDictionary *testConstants = nil;
|
||||||
NSDictionary *testModuleConfig = remoteModuleConfig[@"TestModule"];
|
__block NSNumber *testMethodID = nil;
|
||||||
NSNumber *testModuleID = testModuleConfig[@"moduleID"];
|
|
||||||
NSDictionary *methods = testModuleConfig[@"methods"];
|
NSArray *remoteModuleConfig = RCTJSONParse(injectedStuff, NULL)[@"remoteModuleConfig"];
|
||||||
NSDictionary *testMethod = methods[@"testMethod"];
|
[remoteModuleConfig enumerateObjectsUsingBlock:^(id moduleConfig, NSUInteger i, __unused BOOL *stop) {
|
||||||
NSNumber *testMethodID = testMethod[@"methodID"];
|
if ([moduleConfig isKindOfClass:[NSArray class]] && [moduleConfig[0] isEqualToString:@"TestModule"]) {
|
||||||
|
testModuleID = @(i);
|
||||||
|
testConstants = moduleConfig[1];
|
||||||
|
testMethodID = @([moduleConfig[2] indexOfObject:@"testMethod"]);
|
||||||
|
*stop = YES;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
NSArray *args = @[@1234, @5678, @"stringy", @{@"a": @1}, @42];
|
NSArray *args = @[@1234, @5678, @"stringy", @{@"a": @1}, @42];
|
||||||
NSArray *buffer = @[@[testModuleID], @[testMethodID], @[args], @[], @1234567];
|
NSArray *buffer = @[@[testModuleID], @[testMethodID], @[args], @[], @1234567];
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ let MIN_TIME_BETWEEN_FLUSHES_MS = 5;
|
|||||||
let SPY_MODE = false;
|
let SPY_MODE = false;
|
||||||
|
|
||||||
let MethodTypes = keyMirror({
|
let MethodTypes = keyMirror({
|
||||||
local: null,
|
|
||||||
remote: null,
|
remote: null,
|
||||||
remoteAsync: null,
|
remoteAsync: null,
|
||||||
});
|
});
|
||||||
@@ -62,15 +61,18 @@ class MessageQueue {
|
|||||||
'flushedQueue',
|
'flushedQueue',
|
||||||
].forEach((fn) => this[fn] = this[fn].bind(this));
|
].forEach((fn) => this[fn] = this[fn].bind(this));
|
||||||
|
|
||||||
this._genModules(remoteModules);
|
let modulesConfig = this._genModulesConfig(remoteModules);
|
||||||
|
this._genModules(modulesConfig);
|
||||||
localModules && this._genLookupTables(
|
localModules && this._genLookupTables(
|
||||||
localModules, this._moduleTable, this._methodTable);
|
this._genModulesConfig(localModules),this._moduleTable, this._methodTable
|
||||||
|
);
|
||||||
|
|
||||||
this._debugInfo = {};
|
this._debugInfo = {};
|
||||||
this._remoteModuleTable = {};
|
this._remoteModuleTable = {};
|
||||||
this._remoteMethodTable = {};
|
this._remoteMethodTable = {};
|
||||||
this._genLookupTables(
|
this._genLookupTables(
|
||||||
remoteModules, this._remoteModuleTable, this._remoteMethodTable);
|
modulesConfig, this._remoteModuleTable, this._remoteMethodTable
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -182,54 +184,102 @@ class MessageQueue {
|
|||||||
/**
|
/**
|
||||||
* Private helper methods
|
* Private helper methods
|
||||||
*/
|
*/
|
||||||
_genLookupTables(localModules, moduleTable, methodTable) {
|
|
||||||
let moduleNames = Object.keys(localModules);
|
|
||||||
for (var i = 0, l = moduleNames.length; i < l; i++) {
|
|
||||||
let moduleName = moduleNames[i];
|
|
||||||
let methods = localModules[moduleName].methods || {};
|
|
||||||
let moduleID = localModules[moduleName].moduleID;
|
|
||||||
moduleTable[moduleID] = moduleName;
|
|
||||||
methodTable[moduleID] = {};
|
|
||||||
|
|
||||||
let methodNames = Object.keys(methods);
|
/**
|
||||||
for (var j = 0, k = methodNames.length; j < k; j++) {
|
* Converts the old, object-based module structure to the new
|
||||||
let methodName = methodNames[j];
|
* array-based structure. TODO (t8823865) Removed this
|
||||||
let methodConfig = methods[methodName];
|
* function once Android has been updated.
|
||||||
methodTable[moduleID][methodConfig.methodID] = methodName;
|
*/
|
||||||
|
_genModulesConfig(modules /* array or object */) {
|
||||||
|
if (Array.isArray(modules)) {
|
||||||
|
return modules;
|
||||||
|
} else {
|
||||||
|
let moduleArray = [];
|
||||||
|
let moduleNames = Object.keys(modules);
|
||||||
|
for (var i = 0, l = moduleNames.length; i < l; i++) {
|
||||||
|
let moduleName = moduleNames[i];
|
||||||
|
let moduleConfig = modules[moduleName];
|
||||||
|
let module = [moduleName];
|
||||||
|
if (moduleConfig.constants) {
|
||||||
|
module.push(moduleConfig.constants);
|
||||||
|
}
|
||||||
|
let methodsConfig = moduleConfig.methods;
|
||||||
|
if (methodsConfig) {
|
||||||
|
let methods = [];
|
||||||
|
let asyncMethods = [];
|
||||||
|
let methodNames = Object.keys(methodsConfig);
|
||||||
|
for (var j = 0, ll = methodNames.length; j < ll; j++) {
|
||||||
|
let methodName = methodNames[j];
|
||||||
|
let methodConfig = methodsConfig[methodName];
|
||||||
|
methods[methodConfig.methodID] = methodName;
|
||||||
|
if (methodConfig.type === MethodTypes.remoteAsync) {
|
||||||
|
asyncMethods.push(methodConfig.methodID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (methods.length) {
|
||||||
|
module.push(methods);
|
||||||
|
if (asyncMethods.length) {
|
||||||
|
module.push(asyncMethods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moduleArray[moduleConfig.moduleID] = module;
|
||||||
}
|
}
|
||||||
|
return moduleArray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_genLookupTables(modulesConfig, moduleTable, methodTable) {
|
||||||
|
modulesConfig.forEach((module, moduleID) => {
|
||||||
|
if (!module) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let moduleName, methods;
|
||||||
|
if (moduleHasConstants(module)) {
|
||||||
|
[moduleName, , methods] = module;
|
||||||
|
} else {
|
||||||
|
[moduleName, methods] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleTable[moduleID] = moduleName;
|
||||||
|
methodTable[moduleID] = Object.assign({}, methods);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_genModules(remoteModules) {
|
_genModules(remoteModules) {
|
||||||
let moduleNames = Object.keys(remoteModules);
|
remoteModules.forEach((module, moduleID) => {
|
||||||
for (var i = 0, l = moduleNames.length; i < l; i++) {
|
if (!module) {
|
||||||
let moduleName = moduleNames[i];
|
return;
|
||||||
let moduleConfig = remoteModules[moduleName];
|
}
|
||||||
|
|
||||||
|
let moduleName, constants, methods, asyncMethods;
|
||||||
|
if (moduleHasConstants(module)) {
|
||||||
|
[moduleName, constants, methods, asyncMethods] = module;
|
||||||
|
} else {
|
||||||
|
[moduleName, methods, asyncMethods] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleConfig = {moduleID, constants, methods, asyncMethods};
|
||||||
this.RemoteModules[moduleName] = this._genModule({}, moduleConfig);
|
this.RemoteModules[moduleName] = this._genModule({}, moduleConfig);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_genModule(module, moduleConfig) {
|
_genModule(module, moduleConfig) {
|
||||||
let methods = moduleConfig.methods || {};
|
const {moduleID, constants, methods = [], asyncMethods = []} = moduleConfig;
|
||||||
let methodNames = Object.keys(methods);
|
|
||||||
for (var i = 0, l = methodNames.length; i < l; i++) {
|
methods.forEach((methodName, methodID) => {
|
||||||
let methodName = methodNames[i];
|
const methodType =
|
||||||
let methodConfig = methods[methodName];
|
arrayContains(asyncMethods, methodID) ?
|
||||||
module[methodName] = this._genMethod(
|
MethodTypes.remoteAsync : MethodTypes.remote;
|
||||||
moduleConfig.moduleID,
|
module[methodName] = this._genMethod(moduleID, methodID, methodType);
|
||||||
methodConfig.methodID,
|
});
|
||||||
methodConfig.type || MethodTypes.remote
|
Object.assign(module, constants);
|
||||||
);
|
|
||||||
}
|
|
||||||
Object.assign(module, moduleConfig.constants);
|
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
_genMethod(module, method, type) {
|
_genMethod(module, method, type) {
|
||||||
if (type === MethodTypes.local) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fn = null;
|
let fn = null;
|
||||||
let self = this;
|
let self = this;
|
||||||
if (type === MethodTypes.remoteAsync) {
|
if (type === MethodTypes.remoteAsync) {
|
||||||
@@ -264,6 +314,14 @@ class MessageQueue {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function moduleHasConstants(moduleArray: Array<Object|Array<>>): boolean {
|
||||||
|
return !Array.isArray(moduleArray[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayContains<T>(array: Array<T>, value: T): boolean {
|
||||||
|
return array.indexOf(value) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
function createErrorFromErrorData(errorData: {message: string}): Error {
|
function createErrorFromErrorData(errorData: {message: string}): Error {
|
||||||
var {
|
var {
|
||||||
message,
|
message,
|
||||||
|
|||||||
@@ -308,12 +308,9 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void);
|
|||||||
|
|
||||||
- (NSString *)moduleConfig
|
- (NSString *)moduleConfig
|
||||||
{
|
{
|
||||||
NSMutableDictionary *config = [NSMutableDictionary new];
|
NSMutableArray *config = [NSMutableArray new];
|
||||||
for (RCTModuleData *moduleData in _moduleDataByID) {
|
for (RCTModuleData *moduleData in _moduleDataByID) {
|
||||||
NSDictionary *moduleConfig = moduleData.config;
|
[config addObject:moduleData.config];
|
||||||
if (moduleConfig) {
|
|
||||||
config[moduleData.name] = moduleConfig;
|
|
||||||
}
|
|
||||||
if ([moduleData.instance conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
|
if ([moduleData.instance conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
|
||||||
[_frameUpdateObservers addObject:moduleData];
|
[_frameUpdateObservers addObject:moduleData];
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
@property (nonatomic, strong, readonly) Class moduleClass;
|
@property (nonatomic, strong, readonly) Class moduleClass;
|
||||||
@property (nonatomic, copy, readonly) NSString *name;
|
@property (nonatomic, copy, readonly) NSString *name;
|
||||||
@property (nonatomic, copy, readonly) NSArray *methods;
|
@property (nonatomic, copy, readonly) NSArray *methods;
|
||||||
@property (nonatomic, copy, readonly) NSDictionary *config;
|
@property (nonatomic, copy, readonly) NSArray *config;
|
||||||
|
|
||||||
@property (nonatomic, strong) dispatch_queue_t queue;
|
@property (nonatomic, strong) dispatch_queue_t queue;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTModuleMethod.h"
|
#import "RCTModuleMethod.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
@implementation RCTModuleData
|
@implementation RCTModuleData
|
||||||
{
|
{
|
||||||
@@ -79,37 +80,36 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
|
|||||||
return _methods;
|
return _methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)config
|
- (NSArray *)config
|
||||||
{
|
{
|
||||||
if (_constants.count == 0 && self.methods.count == 0) {
|
if (_constants.count == 0 && self.methods.count == 0) {
|
||||||
return nil; // Nothing to export
|
return (id)kCFNull; // Nothing to export
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableDictionary *config = [NSMutableDictionary new];
|
NSMutableArray *methods = self.methods.count ? [NSMutableArray new] : nil;
|
||||||
config[@"moduleID"] = _moduleID;
|
NSMutableArray *asyncMethods = nil;
|
||||||
|
for (id<RCTBridgeMethod> method in self.methods) {
|
||||||
if (_constants) {
|
[methods addObject:method.JSMethodName];
|
||||||
config[@"constants"] = _constants;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSMutableDictionary *methodconfig = [NSMutableDictionary new];
|
|
||||||
[self.methods enumerateObjectsUsingBlock:^(id<RCTBridgeMethod> method, NSUInteger idx, __unused BOOL *stop) {
|
|
||||||
if (method.functionType == RCTFunctionTypePromise) {
|
if (method.functionType == RCTFunctionTypePromise) {
|
||||||
methodconfig[method.JSMethodName] = @{
|
if (!asyncMethods) {
|
||||||
@"methodID": @(idx),
|
asyncMethods = [NSMutableArray new];
|
||||||
@"type": @"remoteAsync",
|
}
|
||||||
};
|
[asyncMethods addObject:@(methods.count)];
|
||||||
} else {
|
|
||||||
methodconfig[method.JSMethodName] = @{
|
|
||||||
@"methodID": @(idx),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}];
|
|
||||||
if (methodconfig.count) {
|
|
||||||
config[@"methods"] = [methodconfig copy];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [config copy];
|
NSMutableArray *config = [NSMutableArray new];
|
||||||
|
[config addObject:_name];
|
||||||
|
if (_constants.count) {
|
||||||
|
[config addObject:_constants];
|
||||||
|
}
|
||||||
|
if (methods) {
|
||||||
|
[config addObject:methods];
|
||||||
|
if (asyncMethods) {
|
||||||
|
[config addObject:asyncMethods];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (dispatch_queue_t)queue
|
- (dispatch_queue_t)queue
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ typedef NS_ENUM(NSUInteger, RCTNullability) {
|
|||||||
|
|
||||||
@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;
|
|
||||||
|
|
||||||
- (instancetype)initWithObjCMethodName:(NSString *)objCMethodName
|
- (instancetype)initWithObjCMethodName:(NSString *)objCMethodName
|
||||||
JSMethodName:(NSString *)JSMethodName
|
JSMethodName:(NSString *)JSMethodName
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
|
|||||||
}
|
}
|
||||||
|
|
||||||
@synthesize JSMethodName = _JSMethodName;
|
@synthesize JSMethodName = _JSMethodName;
|
||||||
|
@synthesize functionType = _functionType;
|
||||||
|
|
||||||
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
|
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
|
||||||
id valueOrType, const char *issue)
|
id valueOrType, const char *issue)
|
||||||
|
|||||||
Reference in New Issue
Block a user