iOS: Ensure that rendering operations are serialized to prevent timing errors
This commit is contained in:
parent
5dd7504a37
commit
81137b8fb8
@ -109,7 +109,14 @@ - (id)findClass:(Class)clz target:(id)target context:(DoricContext *)context met
|
|||||||
const char *retType = methodSignature.methodReturnType;
|
const char *retType = methodSignature.methodReturnType;
|
||||||
if (!strcmp(retType, @encode(void))) {
|
if (!strcmp(retType, @encode(void))) {
|
||||||
ret = nil;
|
ret = nil;
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block);
|
DoricThreadMode mode = [target threadMode:methodName];
|
||||||
|
if (mode == DoricThreadModeUI) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), block);
|
||||||
|
} else if (mode == DoricThreadModeJS) {
|
||||||
|
block();
|
||||||
|
} else {
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block);
|
||||||
|
}
|
||||||
} else if (!strcmp(retType, @encode(id))) {
|
} else if (!strcmp(retType, @encode(id))) {
|
||||||
void *retValue;
|
void *retValue;
|
||||||
block();
|
block();
|
||||||
|
@ -25,10 +25,21 @@
|
|||||||
#import "DoricPromise.h"
|
#import "DoricPromise.h"
|
||||||
#import "DoricRegistry.h"
|
#import "DoricRegistry.h"
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, DoricThreadMode) {
|
||||||
|
DoricThreadModeUI = 1,
|
||||||
|
DoricThreadModeJS = 2,
|
||||||
|
DoricThreadModeIndependent = 3,
|
||||||
|
};
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricNativePlugin : DoricContextHolder
|
@interface DoricNativePlugin : DoricContextHolder
|
||||||
|
/**
|
||||||
|
* Determines which thread this method should run on
|
||||||
|
* @param method name of method
|
||||||
|
* @return thread where this method should run on,default is DoricThreadModeIndependent
|
||||||
|
* */
|
||||||
|
- (DoricThreadMode)threadMode:(NSString *)method;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -23,5 +23,7 @@
|
|||||||
#import "DoricNativePlugin.h"
|
#import "DoricNativePlugin.h"
|
||||||
|
|
||||||
@implementation DoricNativePlugin
|
@implementation DoricNativePlugin
|
||||||
|
- (DoricThreadMode)threadMode:(NSString *)method {
|
||||||
|
return DoricThreadModeIndependent;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -29,60 +29,56 @@
|
|||||||
|
|
||||||
@implementation DoricShaderPlugin
|
@implementation DoricShaderPlugin
|
||||||
|
|
||||||
|
- (DoricThreadMode)threadMode:(NSString *)method {
|
||||||
|
return DoricThreadModeUI;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
|
- (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
|
||||||
if (!argument) {
|
if (!argument) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[self.doricContext.performanceProfile prepare:@"Render"];
|
[self.doricContext.performanceProfile prepare:@"Render"];
|
||||||
__weak typeof(self) _self = self;
|
if (self.doricContext == nil) {
|
||||||
[self.doricContext dispatchToMainQueue:^{
|
return;
|
||||||
__strong typeof(_self) self = _self;
|
}
|
||||||
if (self.doricContext == nil) {
|
[self.doricContext.performanceProfile start:@"Render"];
|
||||||
return;
|
NSString *viewId = [argument optString:@"id"];
|
||||||
}
|
|
||||||
[self.doricContext.performanceProfile start:@"Render"];
|
|
||||||
NSString *viewId = [argument optString:@"id"];
|
|
||||||
|
|
||||||
if (self.doricContext.rootNode.viewId == nil && [@"Root" isEqualToString:[argument optString:@"type"]]) {
|
if (self.doricContext.rootNode.viewId == nil && [@"Root" isEqualToString:[argument optString:@"type"]]) {
|
||||||
self.doricContext.rootNode.viewId = viewId;
|
self.doricContext.rootNode.viewId = viewId;
|
||||||
[self.doricContext.rootNode blend:[argument optObject:@"props"]];
|
[self.doricContext.rootNode blend:[argument optObject:@"props"]];
|
||||||
[self.doricContext.rootNode requestLayout];
|
[self.doricContext.rootNode requestLayout];
|
||||||
} else {
|
} else {
|
||||||
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
|
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
|
||||||
[viewNode blend:[argument optObject:@"props"]];
|
[viewNode blend:[argument optObject:@"props"]];
|
||||||
[viewNode requestLayout];
|
[viewNode requestLayout];
|
||||||
}
|
}
|
||||||
[promise resolve:nil];
|
[promise resolve:nil];
|
||||||
[self.doricContext.performanceProfile end:@"Render"];
|
[self.doricContext.performanceProfile end:@"Render"];
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
|
- (void)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
|
||||||
__weak typeof(self) _self = self;
|
if (self.doricContext == nil) {
|
||||||
[self.doricContext dispatchToMainQueue:^{
|
return;
|
||||||
__strong typeof(_self) self = _self;
|
}
|
||||||
if (self.doricContext == nil) {
|
NSArray *viewIds = [argument optArray:@"viewIds"];
|
||||||
return;
|
id args = argument[@"args"];
|
||||||
}
|
NSString *name = [argument optString:@"name"];
|
||||||
NSArray *viewIds = [argument optArray:@"viewIds"];
|
DoricViewNode *viewNode = nil;
|
||||||
id args = argument[@"args"];
|
for (NSString *viewId in viewIds) {
|
||||||
NSString *name = [argument optString:@"name"];
|
if (!viewNode) {
|
||||||
DoricViewNode *viewNode = nil;
|
viewNode = [self.doricContext targetViewNode:viewId];
|
||||||
for (NSString *viewId in viewIds) {
|
} else {
|
||||||
if (!viewNode) {
|
if ([viewNode isKindOfClass:[DoricSuperNode class]]) {
|
||||||
viewNode = [self.doricContext targetViewNode:viewId];
|
viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId];
|
||||||
} else {
|
|
||||||
if ([viewNode isKindOfClass:[DoricSuperNode class]]) {
|
|
||||||
viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!viewNode) {
|
}
|
||||||
[promise reject:@"Cannot find opposite view"];
|
if (!viewNode) {
|
||||||
} else {
|
[promise reject:@"Cannot find opposite view"];
|
||||||
[self findClass:[viewNode class] target:viewNode method:name promise:promise argument:args];
|
} else {
|
||||||
}
|
[self findClass:[viewNode class] target:viewNode method:name promise:promise argument:args];
|
||||||
}];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)createParamWithMethodName:(NSString *)method promise:(DoricPromise *)promise argument:(id)argument {
|
- (id)createParamWithMethodName:(NSString *)method promise:(DoricPromise *)promise argument:(id)argument {
|
||||||
|
Reference in New Issue
Block a user