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
This commit is contained in:
Kfir Schindelhaim
2019-04-26 10:11:43 -07:00
committed by Facebook Github Bot
parent f00ff72211
commit c764322c1a
4 changed files with 57 additions and 12 deletions

View File

@@ -12,6 +12,7 @@
FB_LINK_REQUIRE_CATEGORY(CKComponent_Sonar) FB_LINK_REQUIRE_CATEGORY(CKComponent_Sonar)
@interface CKComponent (Sonar) @interface CKComponent (Sonar)
@property (assign, nonatomic) NSUInteger flipper_canBeReusedCounter;
- (NSArray<SKNamed<NSDictionary<NSString *, NSObject *> *> *> *)sonar_getData; - (NSArray<SKNamed<NSDictionary<NSString *, NSObject *> *> *> *)sonar_getData;
- (NSDictionary<NSString *, SKNodeUpdateData> *)sonar_getDataMutations; - (NSDictionary<NSString *, SKNodeUpdateData> *)sonar_getDataMutations;

View File

@@ -61,6 +61,10 @@ FB_LINKABLE(CKComponent_Sonar)
if ([self respondsToSelector:@selector(sonar_componentNameOverride)]) { if ([self respondsToSelector:@selector(sonar_componentNameOverride)]) {
return [(id)self 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]); return NSStringFromClass([self class]);
} }
@@ -98,10 +102,19 @@ FB_LINKABLE(CKComponent_Sonar)
NSMutableArray<SKNamed<NSDictionary<NSString *, NSObject *> *> *> *data = [NSMutableArray new]; NSMutableArray<SKNamed<NSDictionary<NSString *, NSObject *> *> *> *data = [NSMutableArray new];
[data addObject: [SKNamed newWithName: @"CKComponent" [data addObject: [SKNamed newWithName: @"CKComponent"
withValue: @{ withValue: @{
@"frame": SKObject(self.viewContext.frame), @"frame": SKObject(self.viewContext.frame),
@"controller": SKObject(NSStringFromClass([self.controller class])), @"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) { if (self.viewContext.view) {
auto _actions = _CKComponentDebugControlActionsForComponent(self); 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 @end
#endif #endif

View File

@@ -144,10 +144,10 @@
} }
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(SKComponentLayoutWrapper *)node { - (NSArray<SKNamed<NSString *> *> *)attributesForNode:(SKComponentLayoutWrapper *)node {
return @[ NSMutableArray<SKNamed<NSString *> *> *attributes = [NSMutableArray array];
[SKNamed newWithName: @"responder" [attributes addObject:[SKNamed newWithName:@"responder"
withValue: SKObject(NSStringFromClass([node.component.nextResponder class]))] withValue:SKObject(NSStringFromClass([node.component.nextResponder class]))]];
]; return attributes;
} }
- (void)setHighlighted:(BOOL)highlighted forNode:(SKComponentLayoutWrapper *)node { - (void)setHighlighted:(BOOL)highlighted forNode:(SKComponentLayoutWrapper *)node {

View File

@@ -9,12 +9,16 @@
#import "SKComponentLayoutWrapper.h" #import "SKComponentLayoutWrapper.h"
#import <ComponentKit/CKAnalyticsListenerHelpers.h>
#import <ComponentKit/CKComponent.h> #import <ComponentKit/CKComponent.h>
#import <ComponentKit/CKComponentInternal.h>
#import <ComponentKit/CKComponentRootView.h> #import <ComponentKit/CKComponentRootView.h>
#import <ComponentKit/CKComponentAttachController.h> #import <ComponentKit/CKComponentAttachController.h>
#import <ComponentKit/CKComponentAttachControllerInternal.h> #import <ComponentKit/CKComponentAttachControllerInternal.h>
#import <ComponentKit/CKInspectableView.h> #import <ComponentKit/CKInspectableView.h>
#import "CKComponent+Sonar.h"
static char const kLayoutWrapperKey = ' '; static char const kLayoutWrapperKey = ' ';
static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKComponent *child) { static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKComponent *child) {
@@ -41,22 +45,36 @@ static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKCo
+ (instancetype)newFromRoot:(id<CKInspectableView>)root { + (instancetype)newFromRoot:(id<CKInspectableView>)root {
const CKComponentLayout layout = [root mountedLayout]; const CKComponentLayout layout = [root mountedLayout];
CKComponentReuseWrapper *reuseWrapper = CKAnalyticsListenerHelpers::GetReusedNodes(layout.component);
SKComponentLayoutWrapper *const wrapper = SKComponentLayoutWrapper *const wrapper =
[[SKComponentLayoutWrapper alloc] initWithLayout:layout [[SKComponentLayoutWrapper alloc] initWithLayout:layout
position:CGPointMake(0, 0) position:CGPointMake(0, 0)
parentKey:[NSString stringWithFormat: @"%p.", layout.component]]; parentKey:[NSString stringWithFormat: @"%p.", layout.component]
if (layout.component) reuseWrapper:reuseWrapper];
if (layout.component) {
objc_setAssociatedObject(layout.component, &kLayoutWrapperKey, wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(layout.component, &kLayoutWrapperKey, wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return wrapper; 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]) { if (self = [super init]) {
_component = layout.component; _component = layout.component;
_size = layout.size; _size = layout.size;
_position = position; _position = position;
_identifier = [parentKey stringByAppendingString:layout.component ? NSStringFromClass([layout.component class]) : @"(null)"]; _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) { if (layout.children != nullptr) {
int index = 0; int index = 0;
for (const auto &child : *layout.children) { for (const auto &child : *layout.children) {
@@ -65,7 +83,8 @@ static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKCo
} }
SKComponentLayoutWrapper *childWrapper = [[SKComponentLayoutWrapper alloc] initWithLayout:child.layout SKComponentLayoutWrapper *childWrapper = [[SKComponentLayoutWrapper alloc] initWithLayout:child.layout
position:child.position position:child.position
parentKey:[_identifier stringByAppendingFormat:@"[%d].", index++]]; parentKey:[_identifier stringByAppendingFormat:@"[%d].", index++]
reuseWrapper:reuseWrapper];
childWrapper->_isFlexboxChild = [_component isKindOfClass:[CKFlexboxComponent class]]; childWrapper->_isFlexboxChild = [_component isKindOfClass:[CKFlexboxComponent class]];
childWrapper->_flexboxChild = findFlexboxLayoutParams(_component, child.layout.component); childWrapper->_flexboxChild = findFlexboxLayoutParams(_component, child.layout.component);
_children.push_back(childWrapper); _children.push_back(childWrapper);