From c764322c1a70ab54842b92a0f592bb6c782df1ba Mon Sep 17 00:00:00 2001 From: Kfir Schindelhaim Date: Fri, 26 Apr 2019 10:11:43 -0700 Subject: [PATCH] Layout plugin integration for reused nodes information Summary: - Expose the reused component counter into the layout plugin https://pxl.cl/wVJf Reviewed By: priteshrnandgaonkar Differential Revision: D14952906 fbshipit-source-id: 784a02dbf44d80d95fdd3a804f58ecd0f51a3e1f --- .../CKComponent+Sonar.h | 1 + .../CKComponent+Sonar.mm | 33 ++++++++++++++++--- .../SKComponentLayoutDescriptor.mm | 8 ++--- .../SKComponentLayoutWrapper.mm | 27 ++++++++++++--- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.h b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.h index 434ae14b7..c521c7e4e 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.h +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.h @@ -12,6 +12,7 @@ FB_LINK_REQUIRE_CATEGORY(CKComponent_Sonar) @interface CKComponent (Sonar) +@property (assign, nonatomic) NSUInteger flipper_canBeReusedCounter; - (NSArray *> *> *)sonar_getData; - (NSDictionary *)sonar_getDataMutations; diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.mm index acde5a09f..8de3225e2 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/CKComponent+Sonar.mm @@ -61,6 +61,10 @@ FB_LINKABLE(CKComponent_Sonar) if ([self respondsToSelector:@selector(sonar_componentNameOverride)]) { return [(id)self sonar_componentNameOverride]; } + auto const canBeReusedCounter = self.flipper_canBeReusedCounter; + if (canBeReusedCounter > 0) { + return [NSString stringWithFormat:@"%@ (Can be reused x%lu)", NSStringFromClass([self class]), (unsigned long)canBeReusedCounter]; + } return NSStringFromClass([self class]); } @@ -98,10 +102,19 @@ FB_LINKABLE(CKComponent_Sonar) NSMutableArray *> *> *data = [NSMutableArray new]; [data addObject: [SKNamed newWithName: @"CKComponent" - withValue: @{ - @"frame": SKObject(self.viewContext.frame), - @"controller": SKObject(NSStringFromClass([self.controller class])), - }]]; + withValue: @{ + @"frame": SKObject(self.viewContext.frame), + @"controller": SKObject(NSStringFromClass([self.controller class])), + }]]; + + auto const canBeReusedCounter = self.flipper_canBeReusedCounter; + if (canBeReusedCounter > 0) { + [data addObject: [SKNamed newWithName: @"Convert to CKRenderComponent" + withValue: @{ + @"This component can be reused" : + SKObject([NSString stringWithFormat:@"%lu times", (unsigned long)canBeReusedCounter]) + }]]; + } if (self.viewContext.view) { auto _actions = _CKComponentDebugControlActionsForComponent(self); @@ -172,6 +185,18 @@ FB_LINKABLE(CKComponent_Sonar) }; } +static char const kCanBeReusedKey = ' '; + +- (void)setFlipper_canBeReusedCounter:(NSUInteger)canBeReusedCounter +{ + objc_setAssociatedObject(self, &kCanBeReusedKey, @(canBeReusedCounter), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSUInteger)flipper_canBeReusedCounter +{ + return [objc_getAssociatedObject(self, &kCanBeReusedKey) unsignedIntegerValue]; +} + @end #endif diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm index a3211d9b3..ca086e092 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm @@ -144,10 +144,10 @@ } - (NSArray *> *)attributesForNode:(SKComponentLayoutWrapper *)node { - return @[ - [SKNamed newWithName: @"responder" - withValue: SKObject(NSStringFromClass([node.component.nextResponder class]))] - ]; + NSMutableArray *> *attributes = [NSMutableArray array]; + [attributes addObject:[SKNamed newWithName:@"responder" + withValue:SKObject(NSStringFromClass([node.component.nextResponder class]))]]; + return attributes; } - (void)setHighlighted:(BOOL)highlighted forNode:(SKComponentLayoutWrapper *)node { diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm index e92e5befb..215d780b1 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm @@ -9,12 +9,16 @@ #import "SKComponentLayoutWrapper.h" +#import #import +#import #import #import #import #import +#import "CKComponent+Sonar.h" + static char const kLayoutWrapperKey = ' '; static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKComponent *child) { @@ -41,22 +45,36 @@ static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKCo + (instancetype)newFromRoot:(id)root { const CKComponentLayout layout = [root mountedLayout]; + CKComponentReuseWrapper *reuseWrapper = CKAnalyticsListenerHelpers::GetReusedNodes(layout.component); SKComponentLayoutWrapper *const wrapper = [[SKComponentLayoutWrapper alloc] initWithLayout:layout position:CGPointMake(0, 0) - parentKey:[NSString stringWithFormat: @"%p.", layout.component]]; - if (layout.component) + parentKey:[NSString stringWithFormat: @"%p.", layout.component] + reuseWrapper:reuseWrapper]; + if (layout.component) { objc_setAssociatedObject(layout.component, &kLayoutWrapperKey, wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } return wrapper; } -- (instancetype)initWithLayout:(const CKComponentLayout &)layout position:(CGPoint)position parentKey:(NSString *)parentKey { +- (instancetype)initWithLayout:(const CKComponentLayout &)layout + position:(CGPoint)position + parentKey:(NSString *)parentKey + reuseWrapper:(CKComponentReuseWrapper *)reuseWrapper +{ if (self = [super init]) { _component = layout.component; _size = layout.size; _position = position; _identifier = [parentKey stringByAppendingString:layout.component ? NSStringFromClass([layout.component class]) : @"(null)"]; + if (_component && reuseWrapper) { + auto const canBeReusedCounter = [reuseWrapper canBeReusedCounter:_component.treeNode.nodeIdentifier]; + if (canBeReusedCounter > 0) { + _component.flipper_canBeReusedCounter = canBeReusedCounter; + } + } + if (layout.children != nullptr) { int index = 0; for (const auto &child : *layout.children) { @@ -65,7 +83,8 @@ static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKCo } SKComponentLayoutWrapper *childWrapper = [[SKComponentLayoutWrapper alloc] initWithLayout:child.layout position:child.position - parentKey:[_identifier stringByAppendingFormat:@"[%d].", index++]]; + parentKey:[_identifier stringByAppendingFormat:@"[%d].", index++] + reuseWrapper:reuseWrapper]; childWrapper->_isFlexboxChild = [_component isKindOfClass:[CKFlexboxComponent class]]; childWrapper->_flexboxChild = findFlexboxLayoutParams(_component, child.layout.component); _children.push_back(childWrapper);