Added deferred module loading feature

Reviewed By: javache

Differential Revision: D2717687

fb-gh-sync-id: 4c03c721c794a2e7ac67a0b20474129fde7f0a0d
This commit is contained in:
Nick Lockwood
2015-12-10 04:27:45 -08:00
committed by facebook-github-bot-7
parent 5775d9e1d0
commit d138403c2e
6 changed files with 176 additions and 119 deletions

View File

@@ -128,7 +128,7 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
dispatch_group_leave(initModulesAndLoadSource);
}];
// Synchronously initialize all native modules that cannot be deferred
// Synchronously initialize all native modules that cannot be loaded lazily
[self initModules];
#if RCT_DEBUG
@@ -236,16 +236,21 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
- (id)moduleForName:(NSString *)moduleName
{
RCTModuleData *moduleData = _moduleDataByName[moduleName];
if (RCT_DEBUG) {
Class moduleClass = moduleData.moduleClass;
if (!RCTBridgeModuleClassIsRegistered(moduleClass)) {
RCTLogError(@"Class %@ was not exported. Did you forget to use "
"RCT_EXPORT_MODULE()?", moduleClass);
}
}
return moduleData.instance;
}
- (NSArray *)configForModuleName:(NSString *)moduleName
{
RCTModuleData *moduleData = _moduleDataByName[moduleName];
if (!moduleData) {
moduleData = _moduleDataByName[[@"RCT" stringByAppendingString:moduleName]];
}
if (moduleData) {
return moduleData.config;
}
return (id)kCFNull;
}
- (void)initModules
{
RCTAssertMainThread();
@@ -344,21 +349,29 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
[_javaScriptExecutor setUp];
}
- (void)registerModuleForFrameUpdates:(RCTModuleData *)moduleData
{
if ([moduleData.moduleClass conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
[_frameUpdateObservers addObject:moduleData];
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
__weak typeof(self) weakSelf = self;
__weak typeof(_javaScriptExecutor) weakJavaScriptExecutor = _javaScriptExecutor;
observer.pauseCallback = ^{
[weakJavaScriptExecutor executeBlockOnJavaScriptQueue:^{
[weakSelf updateJSDisplayLinkState];
}];
};
}
}
- (NSString *)moduleConfig
{
NSMutableArray<NSArray *> *config = [NSMutableArray new];
for (RCTModuleData *moduleData in _moduleDataByID) {
[config addObject:RCTNullIfNil(moduleData.config)];
if ([moduleData.moduleClass conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
[_frameUpdateObservers addObject:moduleData];
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
__weak typeof(self) weakSelf = self;
__weak typeof(_javaScriptExecutor) weakJavaScriptExecutor = _javaScriptExecutor;
observer.pauseCallback = ^{
[weakJavaScriptExecutor executeBlockOnJavaScriptQueue:^{
[weakSelf updateJSDisplayLinkState];
}];
};
if (self.executorClass == [RCTContextExecutor class]) {
[config addObject:@[moduleData.name]];
} else {
[config addObject:RCTNullIfNil(moduleData.config)];
}
}

View File

@@ -14,6 +14,12 @@
#import "RCTLog.h"
#import "RCTUtils.h"
@interface RCTBridge (Private)
- (void)registerModuleForFrameUpdates:(RCTModuleData *)moduleData;
@end
@implementation RCTModuleData
{
NSString *_queueName;
@@ -88,6 +94,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
"or provide your own setter method.", self.name);
}
}
[bridge registerModuleForFrameUpdates:self];
}
- (NSString *)name

View File

@@ -98,10 +98,11 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
@end
// Private bridge interface to allow middle-batch calls
// Private bridge interface
@interface RCTBridge (RCTContextExecutor)
- (void)handleBuffer:(NSArray<NSArray *> *)buffer batchEnded:(BOOL)hasEnded;
- (NSArray *)configForModuleName:(NSString *)moduleName;
@end
@@ -351,13 +352,24 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
[strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"];
[strongSelf _addNativeHook:RCTNoop withName:"noop"];
__weak RCTBridge *bridge = strongSelf->_bridge;
__weak RCTBridge *weakBridge = strongSelf->_bridge;
strongSelf->_context.context[@"nativeRequireModuleConfig"] = ^NSString *(NSString *moduleName) {
if (!weakSelf.valid) {
return nil;
}
NSArray *config = [weakBridge configForModuleName:moduleName];
if (config) {
return RCTJSONStringify(config, NULL);
}
return nil;
};
strongSelf->_context.context[@"nativeFlushQueueImmediate"] = ^(NSArray<NSArray *> *calls){
if (!weakSelf.valid || !calls) {
return;
}
[bridge handleBuffer:calls batchEnded:NO];
[weakBridge handleBuffer:calls batchEnded:NO];
};
strongSelf->_context.context[@"RCTPerformanceNow"] = ^{
@@ -365,6 +377,7 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
};
#if RCT_DEV
if (RCTProfileIsProfiling()) {
strongSelf->_context.context[@"__RCTProfileIsProfiling"] = @YES;
}
@@ -394,7 +407,9 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
name:event
object:nil];
}
#endif
}];
}
@@ -417,7 +432,6 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
JSStringRef JSName = JSStringCreateWithUTF8CString(name);
JSObjectSetProperty(_context.ctx, globalObject, JSName, JSObjectMakeFunctionWithCallback(_context.ctx, JSName, hook), kJSPropertyAttributeNone, NULL);
JSStringRelease(JSName);
}
- (void)invalidate