Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a centralized configuration API #747

Merged
merged 29 commits into from
Mar 25, 2018
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2c7e050
Update the dangerfile
Jan 15, 2018
1de26b4
Make a trivial change to test new dangerfile
Jan 15, 2018
13fccb0
Try out the new value with another trivial change
Jan 15, 2018
c4b4d09
Add a configuration API to make a unified place for pulling config fr…
Jan 15, 2018
6968445
Specify properties for delegate
Jan 15, 2018
348e5c2
Finish removing text experiment global enable
Jan 15, 2018
f7bd45a
Generate the config file
Jan 15, 2018
2233852
Clean up configuration to fix tests
Jan 15, 2018
1044620
Work on making it serializable
Jan 15, 2018
d02b36f
Merge branch 'master' into AHExperiments
Adlai-Holler Jan 15, 2018
75922a3
Finish it up
Jan 16, 2018
9801560
Fix example code
Jan 16, 2018
99b3a70
Update sample project
Jan 16, 2018
241eec9
Merge branch 'master' into AHExperiments
Adlai-Holler Jan 30, 2018
e4f6aac
Merge branch 'master' into AHExperiments
appleguy Feb 26, 2018
042d338
Clean up a few things
Feb 28, 2018
50383b5
Merge branch 'master' into AHExperiments
Mar 24, 2018
a548185
Align with new project order
Mar 24, 2018
9ab0562
Make it faster and update license header
Mar 24, 2018
0edeb2f
Add an option to specify your config at compile time
Mar 24, 2018
9938217
Update another license header
Mar 24, 2018
4363c6c
Add a version field, and bring interface state coalescing into config…
Mar 24, 2018
1d4ba50
Update CA queue code
Mar 25, 2018
5c5e93d
Update CATransactionQueue tests
Mar 25, 2018
8cb7b8e
Turn transaction queue on by default (for now, see comment)
Mar 25, 2018
681bebd
Update the tests
Mar 25, 2018
16fab3f
Update the tests AGAIN
Mar 25, 2018
331d70d
Merge branch 'master' into AHExperiments
Adlai-Holler Mar 25, 2018
73efad5
Remove unused ordered set
Mar 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions AsyncDisplayKit.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [ASCollectionNode] Added support for interactive item movement. [Adlai Holler](https://github.com/Adlai-Holler)
- Added an experimental "no-copy" rendering API. See ASGraphicsContext.h for info. [Adlai Holler](https://github.com/Adlai-Holler)
- Dropped support for iOS 8. [Adlai Holler](https://github.com/Adlai-Holler)
- Added a configuration API – a unified place to turn on/off experimental Texture features. See `ASConfiguration.h` for info. [Adlai Holler](https://github.com/Adlai-Holler)
- **Breaking** Changes to ASNetworkImageNode: [Adlai Holler](https://github.com/Adlai-Holler)
- Modified `ASImageDownloaderCompletion` to add an optional `id userInfo` field. Your custom downloader can pass `nil`.
- Modified the last argument to `-[ASNetworkImageNodeDelegate imageNode:didLoadImage:info:]` method from a struct to an object of new class `ASNetworkImageLoadInfo` which includes other metadata about the load operation.
Expand Down
19 changes: 19 additions & 0 deletions Schemas/configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"id": "configuration.json",
"title": "configuration",
"description" : "Schema definition of a Texture Configuration",
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"experimental_features": {
"type": "array",
"items": {
"type": "string",
"enum": [
"exp_graphics_contexts",
"exp_text_node"
]
}
}
}
}
55 changes: 55 additions & 0 deletions Source/ASConfiguration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// ASConfiguration.h
// Texture
//
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASExperimentalFeatures.h>

@protocol ASConfigurationDelegate;

NS_ASSUME_NONNULL_BEGIN

AS_SUBCLASSING_RESTRICTED
@interface ASConfiguration : NSObject <NSCopying>

/**
* Initialize this configuration with the provided dictionary,
* or nil to create an empty configuration.
*
* The schema is located in `schemas/configuration.json`.
*/
- (instancetype)initWithDictionary:(nullable NSDictionary *)dictionary;

/**
* The delegate for configuration-related events.
* Delegate methods are called from a serial queue.
*/
@property (strong, nullable) id<ASConfigurationDelegate> delegate;

/**
* The experimental features to enable in Texture.
* See ASExperimentalFeatures for functions to convert to/from a string array.
*/
@property ASExperimentalFeatures experimentalFeatures;

@end

/**
* Implement this method in a category to make your
* configuration available to Texture. It will be read
* only once and copied.
*/
@interface ASConfiguration (UserProvided)
+ (ASConfiguration *)textureConfiguration;
@end

NS_ASSUME_NONNULL_END
40 changes: 40 additions & 0 deletions Source/ASConfiguration.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// ASConfiguration.m
// Texture
//
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <AsyncDisplayKit/ASConfiguration.h>
#import <AsyncDisplayKit/ASConfigurationInternal.h>

/// Not too performance-sensitive here.

/// Get this from C++, without the extra exception handling.
#define autotype __auto_type

@implementation ASConfiguration

- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
if (self = [super init]) {
autotype featureStrings = ASDynamicCast(dictionary[@"experimental_features"], NSArray);
self.experimentalFeatures = ASExperimentalFeaturesFromArray(featureStrings);
}
return self;
}

- (id)copyWithZone:(NSZone *)zone
{
ASConfiguration *config = [[ASConfiguration alloc] initWithDictionary:nil];
config.experimentalFeatures = self.experimentalFeatures;
config.delegate = self.delegate;
return config;
}

@end
32 changes: 32 additions & 0 deletions Source/ASConfigurationDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// ASConfigurationDelegate.h
// Texture
//
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASConfiguration.h>

NS_ASSUME_NONNULL_BEGIN

/**
* Used to communicate configuration-related events to the client.
*/
@protocol ASConfigurationDelegate <NSObject>
@optional

/**
* Texture performed its first behavior related to the feature(s).
* This can be useful for tracking the impact of the behavior (A/B testing).
*/
- (void)textureDidActivateExperimentalFeatures:(ASExperimentalFeatures)features;

@end

NS_ASSUME_NONNULL_END
35 changes: 35 additions & 0 deletions Source/ASExperimentalFeatures.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// ASExperimentalFeatures.h
// Texture
//
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASBaseDefines.h>

NS_ASSUME_NONNULL_BEGIN
ASDISPLAYNODE_EXTERN_C_BEGIN

/**
* A bit mask of features.
*/
typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) {
ASExperimentalGraphicsContexts = 1 << 0, // exp_graphics_contexts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very exciting, can't wait to see this list grow :).

I wonder how we should handle configuration for other values, like floating points, for e.g. range tuning parameter default values?

Or even a pattern of a configuration payload that is passed into certain components, like ASCollectionNode, where there is a default and it can be overridden on a per-instance basis (optionally) -- that's the case where range tuning would be very useful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For more complex values, I don't think it'll be hard. We just update the configuration schema to add more fields. Range tuning param sets would be probably be in their very own schema. Thoughts?

ASExperimentalTextNode = 1 << 1, // exp_text_node
ASExperimentalFeatureAll = 0xFFFFFFFF
};

/// Convert flags -> name array.
NSArray<NSString *> *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags);

/// Convert name array -> flags.
ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray<NSString *> *array);

ASDISPLAYNODE_EXTERN_C_END
NS_ASSUME_NONNULL_END
44 changes: 44 additions & 0 deletions Source/ASExperimentalFeatures.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// ASExperimentalFeatures.m
// Texture
//
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <AsyncDisplayKit/ASExperimentalFeatures.h>

NSArray<NSString *> *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags)
{
NSArray *allNames = ASCreateOnce((@[@"exp_graphics_contexts",
@"exp_text_node"]));

if (flags == ASExperimentalFeatureAll) {
return allNames;
}

// Go through all names, testing each bit.
NSUInteger i = 0;
return ASArrayByFlatMapping(allNames, NSString *name, ({
(flags & (1 << i++)) ? name : nil;
}));
}

// O(N^2) but with counts this small, it's probably faster
// than hashing the strings.
ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray<NSString *> *array)
{
NSArray *allNames = ASExperimentalFeaturesGetNames(ASExperimentalFeatureAll);
ASExperimentalFeatures result = 0;
for (NSString *str in array) {
NSUInteger i = [allNames indexOfObject:str];
if (i != NSNotFound) {
result |= (1 << i);
}
}
return result;
}
10 changes: 7 additions & 3 deletions Source/ASNetworkImageLoadInfo.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
//
// ASNetworkImageLoadInfo.h
// AsyncDisplayKit
// Texture
//
// Created by Adlai on 1/30/18.
// Copyright © 2018 Facebook. All rights reserved.
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <Foundation/Foundation.h>
Expand Down
10 changes: 7 additions & 3 deletions Source/ASNetworkImageLoadInfo.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
//
// ASNetworkImageLoadInfo.m
// AsyncDisplayKit
// Texture
//
// Created by Adlai on 1/30/18.
// Copyright © 2018 Facebook. All rights reserved.
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <AsyncDisplayKit/ASNetworkImageLoadInfo.h>
Expand Down
22 changes: 0 additions & 22 deletions Source/ASTextNode+Beta.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,6 @@

NS_ASSUME_NONNULL_BEGIN

// When enabled, use ASTextNode2 for subclasses, random instances, or all instances of ASTextNode.
// See ASAvailability.h declaration of ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE for a compile-time option.
typedef NS_OPTIONS(NSUInteger, ASTextNodeExperimentOptions) {
// All subclass instances use the experimental implementation.
ASTextNodeExperimentSubclasses = 1 << 0,
// Random instances of ASTextNode (50% chance) (not subclasses) use experimental impl.
// Useful for profiling with apps that have no custom text node subclasses.
ASTextNodeExperimentRandomInstances = 1 << 1,
// All instances of ASTextNode itself use experimental implementation. Supersedes `.randomInstances`.
ASTextNodeExperimentAllInstances = 1 << 2,
// Add highlighting etc. for debugging.
ASTextNodeExperimentDebugging = 1 << 3
};

@interface ASTextNode ()

/**
Expand All @@ -52,14 +38,6 @@ typedef NS_OPTIONS(NSUInteger, ASTextNodeExperimentOptions) {
*/
@property (nonatomic, assign) UIEdgeInsets textContainerInset;

/**
* Opt in to an experimental implementation of text node. The implementation may improve performance and correctness,
* but may not support all features and has not been thoroughly tested in production.
*
* @precondition You may not call this after allocating any text nodes. You may only call this once.
*/
+ (void)setExperimentOptions:(ASTextNodeExperimentOptions)options;

/**
* Returns YES if this node is using the experimental implementation. NO otherwise. Will not change.
*/
Expand Down
Loading