LKS_HierarchyDetailsHandler.m 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #ifdef SHOULD_COMPILE_LOOKIN_SERVER
  2. //
  3. // LKS_HierarchyDetailsHandler.m
  4. // LookinServer
  5. //
  6. // Created by Li Kai on 2019/6/20.
  7. // https://lookin.work
  8. //
  9. #import "LKS_HierarchyDetailsHandler.h"
  10. #import "LookinDisplayItemDetail.h"
  11. #import "LKS_AttrGroupsMaker.h"
  12. #import "LookinStaticAsyncUpdateTask.h"
  13. #import "LKS_ConnectionManager.h"
  14. #import "LookinServerDefines.h"
  15. #import "LKS_CustomAttrGroupsMaker.h"
  16. #import "LKS_HierarchyDisplayItemsMaker.h"
  17. @interface LKS_HierarchyDetailsHandler ()
  18. @property(nonatomic, strong) NSMutableArray<LookinStaticAsyncUpdateTasksPackage *> *taskPackages;
  19. /// 标识哪些 oid 已经拉取过 attrGroups 了
  20. @property(nonatomic, strong) NSMutableSet<NSNumber *> *attrGroupsSyncedOids;
  21. @property(nonatomic, copy) LKS_HierarchyDetailsHandler_ProgressBlock progressBlock;
  22. @property(nonatomic, copy) LKS_HierarchyDetailsHandler_FinishBlock finishBlock;
  23. @end
  24. @implementation LKS_HierarchyDetailsHandler
  25. - (instancetype)init {
  26. if (self = [super init]) {
  27. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleConnectionDidEnd:) name:LKS_ConnectionDidEndNotificationName object:nil];
  28. self.attrGroupsSyncedOids = [NSMutableSet set];
  29. }
  30. return self;
  31. }
  32. - (void)startWithPackages:(NSArray<LookinStaticAsyncUpdateTasksPackage *> *)packages block:(LKS_HierarchyDetailsHandler_ProgressBlock)progressBlock finishedBlock:(LKS_HierarchyDetailsHandler_FinishBlock)finishBlock {
  33. if (!progressBlock || !finishBlock) {
  34. NSAssert(NO, @"");
  35. return;
  36. }
  37. if (!packages.count) {
  38. finishBlock();
  39. return;
  40. }
  41. self.taskPackages = [packages mutableCopy];
  42. self.progressBlock = progressBlock;
  43. self.finishBlock = finishBlock;
  44. [UIView lks_rebuildGlobalInvolvedRawConstraints];
  45. [self _dequeueAndHandlePackage];
  46. }
  47. - (void)cancel {
  48. [self.taskPackages removeAllObjects];
  49. }
  50. - (void)_dequeueAndHandlePackage {
  51. dispatch_async(dispatch_get_main_queue(), ^{
  52. LookinStaticAsyncUpdateTasksPackage *package = self.taskPackages.firstObject;
  53. if (!package) {
  54. self.finishBlock();
  55. return;
  56. }
  57. // NSLog(@"LookinServer - will handle tasks, count: %@", @(tasks.count));
  58. NSArray<LookinDisplayItemDetail *> *details = [package.tasks lookin_map:^id(NSUInteger idx, LookinStaticAsyncUpdateTask *task) {
  59. LookinDisplayItemDetail *itemDetail = [LookinDisplayItemDetail new];
  60. itemDetail.displayItemOid = task.oid;
  61. id object = [NSObject lks_objectWithOid:task.oid];
  62. if (!object || ![object isKindOfClass:[CALayer class]]) {
  63. itemDetail.failureCode = -1;
  64. return itemDetail;
  65. }
  66. CALayer *layer = object;
  67. if (task.taskType == LookinStaticAsyncUpdateTaskTypeSoloScreenshot) {
  68. UIImage *image = [layer lks_soloScreenshotWithLowQuality:NO];
  69. itemDetail.soloScreenshot = image;
  70. } else if (task.taskType == LookinStaticAsyncUpdateTaskTypeGroupScreenshot) {
  71. UIImage *image = [layer lks_groupScreenshotWithLowQuality:NO];
  72. itemDetail.groupScreenshot = image;
  73. }
  74. BOOL shouldMakeAttr = [self queryIfShouldMakeAttrsFromTask:task];
  75. if (shouldMakeAttr) {
  76. itemDetail.attributesGroupList = [LKS_AttrGroupsMaker attrGroupsForLayer:layer];
  77. NSString *version = task.clientReadableVersion;
  78. if (version.length > 0 && [version lookin_numbericOSVersion] >= 10004) {
  79. LKS_CustomAttrGroupsMaker *maker = [[LKS_CustomAttrGroupsMaker alloc] initWithLayer:layer];
  80. [maker execute];
  81. itemDetail.customAttrGroupList = [maker getGroups];
  82. itemDetail.customDisplayTitle = [maker getCustomDisplayTitle];
  83. itemDetail.danceUISource = [maker getDanceUISource];
  84. }
  85. [self.attrGroupsSyncedOids addObject:@(task.oid)];
  86. }
  87. if (task.needBasisVisualInfo) {
  88. itemDetail.frameValue = [NSValue valueWithCGRect:layer.frame];
  89. itemDetail.boundsValue = [NSValue valueWithCGRect:layer.bounds];
  90. itemDetail.hiddenValue = [NSNumber numberWithBool:layer.isHidden];
  91. itemDetail.alphaValue = @(layer.opacity);
  92. }
  93. if (task.needSubitems) {
  94. itemDetail.subitems = [LKS_HierarchyDisplayItemsMaker subitemsOfLayer:layer];
  95. }
  96. return itemDetail;
  97. }];
  98. self.progressBlock(details);
  99. [self.taskPackages removeObjectAtIndex:0];
  100. [self _dequeueAndHandlePackage];
  101. });
  102. }
  103. - (BOOL)queryIfShouldMakeAttrsFromTask:(LookinStaticAsyncUpdateTask *)task {
  104. switch (task.attrRequest) {
  105. case LookinDetailUpdateTaskAttrRequest_Automatic: {
  106. BOOL alreadyMadeBefore = [self.attrGroupsSyncedOids containsObject:@(task.oid)];
  107. return !alreadyMadeBefore;
  108. }
  109. case LookinDetailUpdateTaskAttrRequest_Need:
  110. return YES;
  111. case LookinDetailUpdateTaskAttrRequest_NotNeed:
  112. return NO;
  113. }
  114. NSAssert(NO, @"");
  115. return YES;
  116. }
  117. - (void)_handleConnectionDidEnd:(id)obj {
  118. [self cancel];
  119. }
  120. @end
  121. #endif /* SHOULD_COMPILE_LOOKIN_SERVER */