...
|
...
|
@@ -8,8 +8,6 @@ |
|
|
|
|
|
#import "YH_WatchDog.h"
|
|
|
#import <objc/runtime.h>
|
|
|
#import "UserModule.h"
|
|
|
#import "ProductModule.h"
|
|
|
#import "UberSignals.h"
|
|
|
|
|
|
NSString * const YH_CallServiceModuleIdKey = @"YH_CallServiceModuleIdKey";
|
...
|
...
|
@@ -80,8 +78,9 @@ NSString *YH_BridgeModuleNameForClass(Class cls) |
|
|
@property (strong, nonatomic) NSArray<YH_ModuleData *> *moduleDataByID;
|
|
|
@property (strong, nonatomic) NSArray<Class> *moduleClassesByID;
|
|
|
|
|
|
@property (assign, nonatomic) NSUInteger syncInitializedModules;
|
|
|
@property (assign, nonatomic) NSUInteger asyncInitializedModules;
|
|
|
@property (nonatomic, copy, readonly) YH_BridgeModuleProviderBlock moduleProvider;
|
|
|
|
|
|
@property (assign, nonatomic) NSUInteger initializedModulesCount;
|
|
|
|
|
|
@end
|
|
|
|
...
|
...
|
@@ -122,23 +121,30 @@ NSString *YH_BridgeModuleNameForClass(Class cls) |
|
|
}
|
|
|
|
|
|
|
|
|
+ (instancetype)sharedInstance
|
|
|
+ (instancetype)dog
|
|
|
{
|
|
|
return [self startWithModuleProvider:nil];
|
|
|
}
|
|
|
|
|
|
+ (instancetype)startWithModuleProvider:(YH_BridgeModuleProviderBlock)block
|
|
|
{
|
|
|
static YH_WatchDog *instance = nil;
|
|
|
static dispatch_once_t onceToken;
|
|
|
dispatch_once(&onceToken, ^{
|
|
|
instance = [[self alloc] init];
|
|
|
instance = [[self alloc] initWithModuleProvider:block];
|
|
|
});
|
|
|
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
- (instancetype)init
|
|
|
- (instancetype)initWithModuleProvider:(YH_BridgeModuleProviderBlock)block
|
|
|
{
|
|
|
self = [super init];
|
|
|
if (self) {
|
|
|
_loading = YES;
|
|
|
_pendingCalls = [NSMutableArray array];
|
|
|
_moduleProvider = block;
|
|
|
|
|
|
[self start];
|
|
|
}
|
|
|
|
...
|
...
|
@@ -150,19 +156,27 @@ NSString *YH_BridgeModuleNameForClass(Class cls) |
|
|
// dispatch_queue_t bridgeQueue = dispatch_queue_create("cn.yoho.watchdog.YH_BridgeQueue", DISPATCH_QUEUE_SERIAL);
|
|
|
|
|
|
[self initModules];
|
|
|
#if DEBUG
|
|
|
_initializedModulesCount = [[_moduleDataByID valueForKeyPath:@"@sum.hasInstance"] integerValue];
|
|
|
#endif
|
|
|
[self didFinishLoading];
|
|
|
|
|
|
}
|
|
|
|
|
|
- (void)initModules
|
|
|
{
|
|
|
if (![NSThread isMainThread]) {
|
|
|
NSLog(@"This function must be called on the main thread");
|
|
|
NSAssert(NO, @"This function must be called on the main thread");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 注册需要预加载的module
|
|
|
NSMutableDictionary *preregisteredModules = [NSMutableDictionary new];
|
|
|
|
|
|
NSArray<id<YH_BridgeModule>> *extraModules = [self perLoadModules];
|
|
|
NSArray<id<YH_BridgeModule>> *extraModules;
|
|
|
if (self.moduleProvider) {
|
|
|
extraModules = self.moduleProvider();
|
|
|
}
|
|
|
|
|
|
for (id<YH_BridgeModule> module in extraModules) {
|
|
|
preregisteredModules[YH_BridgeModuleNameForClass([module class])] = module;
|
...
|
...
|
@@ -228,11 +242,6 @@ NSString *YH_BridgeModuleNameForClass(Class cls) |
|
|
|
|
|
}
|
|
|
|
|
|
- (NSArray<id<YH_BridgeModule>> *)perLoadModules
|
|
|
{
|
|
|
return @[[UserModule new], [ProductModule new]];
|
|
|
}
|
|
|
|
|
|
- (id)moduleForName:(NSString *)moduleName
|
|
|
{
|
|
|
YH_ModuleData *moduleData = _moduleDataByName[moduleName];
|
...
|
...
|
@@ -254,6 +263,14 @@ NSString *YH_BridgeModuleNameForClass(Class cls) |
|
|
return _moduleDataByName[moduleName];
|
|
|
}
|
|
|
|
|
|
- (void)didFinishLoading
|
|
|
{
|
|
|
_loading = NO;
|
|
|
for (dispatch_block_t call in _pendingCalls) {
|
|
|
call();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- (void)allModuleServices
|
|
|
{
|
|
|
NSMutableString *output = [NSMutableString string];
|
...
|
...
|
@@ -319,70 +336,68 @@ NSString *YH_BridgeModuleNameForClass(Class cls) |
|
|
- (void)callService:(NSDictionary *)input observer:(id)observer callbackType:(YH_ServiceCallbackType)callbackType callback:(YH_ServiceCallbackId)callback
|
|
|
{
|
|
|
NSString *moduleId = input[YH_CallServiceModuleIdKey];
|
|
|
NSString *serviceId = input[YH_CallServiceServiceIdKey];
|
|
|
NSDictionary *parameters = input[YH_CallServiceParametersKey] ?: @{};
|
|
|
|
|
|
if (self.loading) {
|
|
|
__weak typeof(self) weakSelf = self;
|
|
|
dispatch_block_t pendingCall = ^{
|
|
|
[weakSelf invokeModule:moduleId service:serviceId parameters:parameters observer:observer callbackType:callbackType callback:callback];
|
|
|
};
|
|
|
[self->_pendingCalls addObject:pendingCall];
|
|
|
} else {
|
|
|
[self invokeModule:moduleId service:serviceId parameters:parameters observer:observer callbackType:callbackType callback:callback];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- (void)invokeModule:(NSString *)moduleId service:(NSString *)serviceId parameters:(NSDictionary *)parameters observer:(id)observer callbackType:(YH_ServiceCallbackType)callbackType callback:(YH_ServiceCallbackId)callback
|
|
|
{
|
|
|
if (!moduleId || [moduleId isEqualToString:@""]) {
|
|
|
#if DEBUG
|
|
|
NSAssert(NO, @"moduleId不能为空");
|
|
|
#else
|
|
|
NSLog(@"moduleId不能为空");
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
NSString *serviceId = input[YH_CallServiceServiceIdKey];
|
|
|
if (!serviceId || [serviceId isEqualToString:@""]) {
|
|
|
#if DEBUG
|
|
|
NSAssert(NO, @"serviceId不能为空");
|
|
|
#else
|
|
|
NSLog(@"serviceId不能为空");
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
NSDictionary *parameters = input[YH_CallServiceParametersKey] ?: @{};
|
|
|
|
|
|
|
|
|
YH_ModuleData *moduleData = _moduleDataByName[moduleId];
|
|
|
if (!moduleData) {
|
|
|
#if DEBUG
|
|
|
NSAssert(NO, @"module: %@ 没有注册", moduleId);
|
|
|
#else
|
|
|
NSLog(@"moduleId: %@ 没有注册", moduleId);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
YH_ModuleService *service = moduleData.services[serviceId];
|
|
|
if (!service) {
|
|
|
#if DEBUG
|
|
|
NSAssert(NO, @"module: %@ 没有 service: %@ 服务", moduleId, serviceId);
|
|
|
#else
|
|
|
NSLog(@"module: %@ 没有 service: %@ 服务", moduleId, serviceId);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
[self enqueueCallModule:moduleData service:service parameters:parameters observer:observer callbackType:callbackType callback:callback];
|
|
|
}
|
|
|
|
|
|
- (void)enqueueCallModule:(YH_ModuleData *)moduleData service:(YH_ModuleService *)service parameters:(NSDictionary *)parameters observer:(id)observer callbackType:(YH_ServiceCallbackType)callbackType callback:(YH_ServiceCallbackId)callback
|
|
|
{
|
|
|
NSMutableDictionary *newParamters = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
|
|
UBSignalObserver *signalObserver = [self observeSignal:service.signal observer:observer callbackType:callbackType callback:callback];
|
|
|
if (signalObserver) {
|
|
|
newParamters[YH_CallServiceObserverKey] = signalObserver;
|
|
|
}
|
|
|
|
|
|
if (service.queue) {
|
|
|
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
|
|
|
[self enqueueCallModule:moduleData service:service parameters:[parameters copy] observer:observer callbackType:callbackType callback:callback];
|
|
|
[self actuallyInvokeModule:moduleData service:service parameters:[newParamters copy]];
|
|
|
}];
|
|
|
|
|
|
[service.queue addOperation:op];
|
|
|
} else {
|
|
|
[self enqueueCallModule:moduleData service:service parameters:[parameters copy] observer:observer callbackType:callbackType callback:callback];
|
|
|
[self actuallyInvokeModule:moduleData service:service parameters:[newParamters copy]];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- (void)enqueueCallModule:(YH_ModuleData *)moduleData service:(YH_ModuleService *)service parameters:(NSDictionary *)parameters observer:(id)observer callbackType:(YH_ServiceCallbackType)callbackType callback:(YH_ServiceCallbackId)callback
|
|
|
- (void)actuallyInvokeModule:(YH_ModuleData *)moduleData service:(YH_ModuleService *)service parameters:(NSDictionary *)parameters
|
|
|
{
|
|
|
dispatch_async(moduleData.serviceQueue, ^{
|
|
|
|
|
|
NSMutableDictionary *newParamters = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
|
|
UBSignalObserver *signalObserver = [self observeSignal:service.signal observer:observer callbackType:callbackType callback:callback];
|
|
|
if (signalObserver) {
|
|
|
newParamters[YH_CallServiceObserverKey] = signalObserver;
|
|
|
}
|
|
|
|
|
|
NSArray *arguments = @[[newParamters copy]];
|
|
|
NSArray *arguments = @[parameters];
|
|
|
[service invokeWithBridge:self module:moduleData.instance arguments:arguments];
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
- (UBSignalObserver *)observeSignal:(UBSignal *)signal observer:observer callbackType:(YH_ServiceCallbackType)callbackType callback:(YH_ServiceCallbackId)callback
|
...
|
...
|
|