Add ability to register additional attribute providers.

Summary:
We have some "internal-only" stuff we want to put in the attribute of a layout node.
This allows us to do so a way that keeps it out of open-source and avoid the clunky subclassing.

Reviewed By: adamjernst

Differential Revision: D24162047

fbshipit-source-id: 518ab9fbf0b4274076f5b0ae1b249e197563fa7f
This commit is contained in:
Dustin Shahidehpour
2020-10-07 15:39:56 -07:00
committed by Facebook GitHub Bot
parent 2b6bac4227
commit 7711502413
2 changed files with 33 additions and 0 deletions

View File

@@ -11,10 +11,20 @@
@class SKComponentLayoutWrapper; @class SKComponentLayoutWrapper;
typedef SKNamed* (*SKAttributeGenerator)(SKComponentLayoutWrapper* node);
@interface SKComponentLayoutDescriptor @interface SKComponentLayoutDescriptor
: SKNodeDescriptor<SKComponentLayoutWrapper*> : SKNodeDescriptor<SKComponentLayoutWrapper*>
+ (void)registerSubDescriptor:(SKSubDescriptor)descriptor + (void)registerSubDescriptor:(SKSubDescriptor)descriptor
forName:(NSString*)name; forName:(NSString*)name;
/**
Allows you to 'plug-in' additional logic to update the attribute
string displayed for a node.
You can return a `nil` object from this, it will be gracefully ignored.
*/
+ (void)registerAttributeGenerator:(SKAttributeGenerator)generator;
@end @end

View File

@@ -41,6 +41,18 @@ static std::vector<std::pair<NSString*, SKSubDescriptor>>& subDescriptors() {
return d; return d;
} }
static std::vector<SKAttributeGenerator>& attributeGenerators() {
// Avoid a global constructor; we want to lazily initialize this when needed.
static std::vector<SKAttributeGenerator> d;
return d;
}
+ (void)registerAttributeGenerator:(SKAttributeGenerator)generator {
if (generator) {
attributeGenerators().push_back(generator);
}
}
+ (void)registerSubDescriptor:(SKSubDescriptor)descriptor + (void)registerSubDescriptor:(SKSubDescriptor)descriptor
forName:(NSString*)name { forName:(NSString*)name {
if (name && descriptor) { if (name && descriptor) {
@@ -170,6 +182,17 @@ static std::vector<std::pair<NSString*, SKSubDescriptor>>& subDescriptors() {
newWithName:@"responder" newWithName:@"responder"
withValue:SKObject(NSStringFromClass( withValue:SKObject(NSStringFromClass(
[node.component.nextResponder class]))]]; [node.component.nextResponder class]))]];
for (SKAttributeGenerator generator : attributeGenerators()) {
if (!generator) {
// technically, this could be nullptr, so lets be careful.
continue;
}
SKNamed* const attribute = generator(node);
if (attribute) {
[attributes addObject:attribute];
}
}
return attributes; return attributes;
} }