Refactor SKSubDescriptor

Reviewed By: d16r

Differential Revision: D20458337

fbshipit-source-id: e8ea848c6e2f7521c5a6c6eb4110bba0bfe25593
This commit is contained in:
Adam Ernst
2020-03-15 19:39:20 -07:00
committed by Facebook GitHub Bot
parent 19876273a3
commit d9a2167019
7 changed files with 27 additions and 107 deletions

View File

@@ -115,50 +115,17 @@ Sometimes all you need is to extend the functionality of an existing descriptor.
### Subdescriptors ### Subdescriptors
If you want to extend the `SKComponentKitLayoutDescriptor` and add an additional section based on the nodes of the `SKComponentLayoutDescriptor`, you will have to subclass `SKSubDescriptor`. If you want to extend the `SKComponentKitLayoutDescriptor` and add an additional section based on the nodes of the `SKComponentLayoutDescriptor`, you can use `SKSubDescriptor`.
```objc ```objc
#import <FlipperKitLayoutComponentKitSupport/SKSubDescriptor.h> #import <FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h>
@interface YourSubDescriptor: SKSubDescriptor NSString *YourSubDescriptor(SKComponentLayoutWrapper *)node {
return @"Meta data";
@end
@implementation YourSubDescriptor
- (NSString *) getName {
return @"Section Name";
} }
- (NSString *)getDataForNode:(SKComponentLayoutWrapper *)node { // At setup time, you must register it:
return @"Meta data" [SKComponentLayoutDescriptor registerSubDescriptor:&YourSubDescriptor forName:@"Section Name"];
}
@end
#endif
``` ```
Once you have implemented the descriptor, you will have to setup the Layout plugin as follows. Swift support is not yet available because you must access `SKComponentLayoutWrapper` to implement a subdescriptor.
<!--DOCUSAURUS_CODE_TABS-->
<!--Objective-C-->
```objc
NSArray<SKSubDescriptor *> *registeredSubDescriptors = @[ yourSubDescriptors ];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[FlipperKitLayoutComponentKitSupport setUpWithDescriptorMapper: layoutDescriptorMapper subDescriptors: registeredSubDescriptors];
[client addPlugin: [[FlipperKitLayoutPlugin alloc] initWithRootNode: application
withDescriptorMapper: layoutDescriptorMapper]];
```
<!--Swift-->
```swift
let subDescriptors = [ yourSubDescriptors ]
let layoutDescriptorMapper = SKDescriptorMapper(defaults: ())
FlipperKitLayoutComponentKitSupport.setUpWith(layoutDescriptorMapper, subDescriptors: subDescriptors)
client?.add(FlipperKitLayoutPlugin(rootNode: application, with: layoutDescriptorMapper!))
```
<!--END_DOCUSAURUS_CODE_TABS-->

View File

@@ -8,13 +8,9 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <FlipperKitLayoutPlugin/SKDescriptorMapper.h> #import <FlipperKitLayoutPlugin/SKDescriptorMapper.h>
#import "SKSubDescriptor.h"
@interface FlipperKitLayoutComponentKitSupport : NSObject @interface FlipperKitLayoutComponentKitSupport : NSObject
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper; + (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper;
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper
subDescriptors:(NSArray<SKSubDescriptor*>*)subDescriptors;
@end @end

View File

@@ -17,22 +17,9 @@
#import "SKComponentLayoutDescriptor.h" #import "SKComponentLayoutDescriptor.h"
#import "SKComponentLayoutWrapper.h" #import "SKComponentLayoutWrapper.h"
#import "SKComponentRootViewDescriptor.h" #import "SKComponentRootViewDescriptor.h"
#import "SKSubDescriptor.h"
@implementation FlipperKitLayoutComponentKitSupport @implementation FlipperKitLayoutComponentKitSupport
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper
subDescriptors:(NSArray<SKSubDescriptor*>*)subDescriptors {
[mapper registerDescriptor:[[SKComponentRootViewDescriptor alloc]
initWithDescriptorMapper:mapper]
forClass:[CKComponentRootView class]];
SKComponentLayoutDescriptor* layoutDescriptor =
[[SKComponentLayoutDescriptor alloc] initWithDescriptorMapper:mapper];
[layoutDescriptor addSubDescriptors:subDescriptors];
[mapper registerDescriptor:layoutDescriptor
forClass:[SKComponentLayoutWrapper class]];
}
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper { + (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper {
// What we really want here is "forProtocol:@protocol(CKInspectableView)" but // What we really want here is "forProtocol:@protocol(CKInspectableView)" but
// no such luck. // no such luck.

View File

@@ -14,6 +14,7 @@
@interface SKComponentLayoutDescriptor @interface SKComponentLayoutDescriptor
: SKNodeDescriptor<SKComponentLayoutWrapper*> : SKNodeDescriptor<SKComponentLayoutWrapper*>
- (void)addSubDescriptors:(NSArray<SKSubDescriptor*>*)subDescriptors; + (void)registerSubDescriptor:(SKSubDescriptor)descriptor
forName:(NSString*)name;
@end @end

View File

@@ -9,6 +9,9 @@
#import "SKComponentLayoutDescriptor.h" #import "SKComponentLayoutDescriptor.h"
#import <utility>
#import <vector>
#import <ComponentKit/CKComponent.h> #import <ComponentKit/CKComponent.h>
#import <ComponentKit/CKComponentAccessibility.h> #import <ComponentKit/CKComponentAccessibility.h>
#import <ComponentKit/CKComponentActionInternal.h> #import <ComponentKit/CKComponentActionInternal.h>
@@ -29,15 +32,18 @@
#import "SKSubDescriptor.h" #import "SKSubDescriptor.h"
#import "Utils.h" #import "Utils.h"
@implementation SKComponentLayoutDescriptor { @implementation SKComponentLayoutDescriptor
NSArray<SKSubDescriptor*>* _registeredSubdescriptors;
static std::vector<std::pair<NSString*, SKSubDescriptor>>& subDescriptors() {
// Avoid a global constructor; we want to lazily initialize this when needed.
static std::vector<std::pair<NSString*, SKSubDescriptor>> d;
return d;
} }
- (void)setUp { + (void)registerSubDescriptor:(SKSubDescriptor)descriptor
[super setUp]; forName:(NSString*)name {
if (name && descriptor) {
if (!_registeredSubdescriptors) { subDescriptors().push_back({name, descriptor});
_registeredSubdescriptors = [NSArray new];
} }
} }
@@ -90,8 +96,8 @@
NSMutableDictionary<NSString*, NSObject*>* extraData = NSMutableDictionary<NSString*, NSObject*>* extraData =
[[NSMutableDictionary alloc] init]; [[NSMutableDictionary alloc] init];
for (SKSubDescriptor* s in _registeredSubdescriptors) { for (const auto& pair : subDescriptors()) {
[extraData setObject:[s getDataForNode:node] forKey:[s getName]]; [extraData setObject:pair.second(node) forKey:pair.first];
} }
if (extraData.count > 0) { if (extraData.count > 0) {
[data addObject:[SKNamed newWithName:@"Extra Sections" [data addObject:[SKNamed newWithName:@"Extra Sections"
@@ -102,10 +108,6 @@
return data; return data;
} }
- (void)addSubDescriptors:(nonnull NSArray<SKSubDescriptor*>*)subDescriptors {
_registeredSubdescriptors = subDescriptors;
}
- (NSDictionary<NSString*, NSObject*>*)propsForFlexboxChild: - (NSDictionary<NSString*, NSObject*>*)propsForFlexboxChild:
(CKFlexboxComponentChild)child { (CKFlexboxComponentChild)child {
return @{ return @{

View File

@@ -10,20 +10,8 @@
@class SKComponentLayoutWrapper; @class SKComponentLayoutWrapper;
/** /**
A SKSubDescriptor is an object which knows how to expose an Object of type T A SKSubDescriptor is a function which knows how to expose additional data
to the SKLayoutDescriptor. This class is for frameworks wanting to pass data to SKLayoutDescriptor. This class is for frameworks wanting to pass data
along through the Layout Descriptor. along through the Layout Descriptor.
*/ */
@interface SKSubDescriptor : NSObject typedef NSString* (*SKSubDescriptor)(SKComponentLayoutWrapper* node);
/**
This is the SubDescriptor name.
*/
- (NSString*)getName;
/**
This is the data the SubDescriptor wants to pass up to the SKLayoutDescriptor.
*/
- (NSString*)getDataForNode:(SKComponentLayoutWrapper*)node;
@end

View File

@@ -4,24 +4,3 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#if FB_SONARKIT_ENABLED
#import "SKSubDescriptor.h"
#import "SKComponentLayoutWrapper.h"
@implementation SKSubDescriptor {
}
- (NSDictionary<NSString*, NSObject*>*)getDataForNode:
(SKComponentLayoutWrapper*)node {
return @{};
}
- (NSString*)getName {
return @"";
}
@end
#endif