Skip to content

Commit

Permalink
Merge branch 'releases/p8.35'
Browse files Browse the repository at this point in the history
* releases/p8.35:
  Do not expose tgmath.h to all clients of Texture (TextureGroup#1900)
  Call will / did display node for ASTextNode. Fixes TextureGroup#1680 (TextureGroup#1893)
  Remove background deallocation helper code (TextureGroup#1890)
  [Accessibility] Ship ASExperimentalDoNotCacheAccessibilityElements (TextureGroup#1888)
  🎉 3.0.0 (TextureGroup#1883)
  • Loading branch information
varyomh committed Sep 15, 2020
2 parents 0c6243c + 45c0f19 commit 5259789
Show file tree
Hide file tree
Showing 18 changed files with 47 additions and 174 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## [3.0.0](https://github.com/TextureGroup/Texture/tree/3.0.0) (2020-07-15)

[Full Changelog](https://github.com/TextureGroup/Texture/compare/3.0.0-rc.2...3.0.0)

**Merged pull requests:**

- Improve ThreeMigrationGuide.md [\#1878](https://github.com/TextureGroup/Texture/pull/1878) ([rogerluan](https://github.com/rogerluan))
- Upgrade to Xcode 11.5 [\#1877](https://github.com/TextureGroup/Texture/pull/1877) ([garrettmoon](https://github.com/garrettmoon))
- Renames AS\_EXTERN and ASViewController [\#1876](https://github.com/TextureGroup/Texture/pull/1876) ([garrettmoon](https://github.com/garrettmoon))
- Add a 3.0 migration guide [\#1875](https://github.com/TextureGroup/Texture/pull/1875) ([garrettmoon](https://github.com/garrettmoon))

## [3.0.0-rc.2](https://github.com/TextureGroup/Texture/tree/3.0.0-rc.2) (2020-06-25)

[Full Changelog](https://github.com/TextureGroup/Texture/compare/3.0.0-rc.1...3.0.0-rc.2)
Expand Down
2 changes: 1 addition & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This document describes the process for a public Texture release.
### Process
- Run `github_changelog_generator` in Texture project directory: `github_changelog_generator --token <generated personal token> --user TextureGroup --project Texture`. To avoid hitting rate limit, the generator will replace the entire file with just the changes from this version – revert that giant deletion to get the entire new changelog.
- Update `spec.version` within `Texture.podspec` and the `since-tag` and `future-release` fields in `.github_changelog_generator`.
- Create a new PR with the updated `Texture.podspec` and the newly generated changelog, add `#changelog` to the PR message so the CI will not prevent merging it.
- Create a new PR with the updated `Texture.podspec` and the newly generated changelog.
- After merging in the PR, [create a new GitHub release](https://github.com/TextureGroup/Texture/releases/new). Use the generated changelog for the new release.
- Push to Cocoapods with `pod trunk push`

Expand Down
1 change: 0 additions & 1 deletion Source/ASExperimentalFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) {
ASExperimentalDispatchApply = 1 << 7, // exp_dispatch_apply
ASExperimentalDrawingGlobal = 1 << 8, // exp_drawing_global
ASExperimentalOptimizeDataControllerPipeline = 1 << 9, // exp_optimize_data_controller_pipeline
ASExperimentalDoNotCacheAccessibilityElements = 1 << 10, // exp_do_not_cache_accessibility_elements
ASExperimentalFeatureAll = 0xFFFFFFFF
};

Expand Down
3 changes: 1 addition & 2 deletions Source/ASExperimentalFeatures.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
@"exp_did_enter_preload_skip_asm_layout",
@"exp_dispatch_apply",
@"exp_drawing_global",
@"exp_optimize_data_controller_pipeline",
@"exp_do_not_cache_accessibility_elements"]));
@"exp_optimize_data_controller_pipeline"]));
if (flags == ASExperimentalFeatureAll) {
return allNames;
}
Expand Down
13 changes: 1 addition & 12 deletions Source/ASRunLoopQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ AS_SUBCLASSING_RESTRICTED
*
* @discussion You may pass @c nil for the handler if you simply want the objects to
* be retained at enqueue time, and released during the run loop step. This is useful
* for creating a "main deallocation queue", as @c ASDeallocQueue creates its own
* worker thread with its own run loop.
* for creating a "main deallocation queue".
*/
- (instancetype)initWithRunLoop:(CFRunLoopRef)runloop
retainObjects:(BOOL)retainsObjects
Expand Down Expand Up @@ -78,14 +77,4 @@ NS_INLINE ASCATransactionQueue *ASCATransactionQueueGet(void) {
return _ASSharedCATransactionQueue;
}

@interface ASDeallocQueue : NSObject

+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED;

- (void)drain;

- (void)releaseObjectInBackground:(id __strong _Nullable * _Nonnull)objectPtr;

@end

NS_ASSUME_NONNULL_END
61 changes: 0 additions & 61 deletions Source/ASRunLoopQueue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,67 +27,6 @@ static void runLoopSourceCallback(void *info) {
#endif
}

#pragma mark - ASDeallocQueue

@implementation ASDeallocQueue {
std::vector<CFTypeRef> _queue;
AS::Mutex _lock;
}

+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED
{
static ASDeallocQueue *deallocQueue = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
deallocQueue = [[ASDeallocQueue alloc] init];
});
return deallocQueue;
}

- (void)dealloc
{
ASDisplayNodeFailAssert(@"Singleton should not dealloc.");
}

- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr
{
NSParameterAssert(objectPtr != NULL);

// Cast to CFType so we can manipulate retain count manually.
const auto cfPtr = (CFTypeRef *)(void *)objectPtr;
if (!cfPtr || !*cfPtr) {
return;
}

_lock.lock();
const auto isFirstEntry = _queue.empty();
// Push the pointer into our queue and clear their pointer.
// This "steals" the +1 from ARC and nils their pointer so they can't
// access or release the object.
_queue.push_back(*cfPtr);
*cfPtr = NULL;
_lock.unlock();

if (isFirstEntry) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.100 * NSEC_PER_SEC)), dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
[self drain];
});
}
}

- (void)drain
{
_lock.lock();
const auto q = std::move(_queue);
_lock.unlock();
for (CFTypeRef ref : q) {
// NOTE: Could check that retain count is 1 and retry later if not.
CFRelease(ref);
}
}

@end

@implementation ASAbstractRunLoopQueue

- (instancetype)init
Expand Down
24 changes: 22 additions & 2 deletions Source/ASTextNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ @interface ASTextNodeDrawParameter : NSObject {
BOOL _opaque;
CGRect _bounds;
ASPrimitiveTraitCollection _traitCollection;
ASDisplayNodeContextModifier _willDisplayNodeContentWithRenderingContext;
ASDisplayNodeContextModifier _didDisplayNodeContentWithRenderingContext;
}
@end

Expand All @@ -152,7 +154,9 @@ - (instancetype)initWithRendererAttributes:(ASTextKitAttributes)rendererAttribut
contentScale:(CGFloat)contentScale
opaque:(BOOL)opaque
bounds:(CGRect)bounds
traitCollection: (ASPrimitiveTraitCollection)traitCollection
traitCollection:(ASPrimitiveTraitCollection)traitCollection
willDisplayNodeContentWithRenderingContext:(ASDisplayNodeContextModifier)willDisplayNodeContentWithRenderingContext
didDisplayNodeContentWithRenderingContext:(ASDisplayNodeContextModifier)didDisplayNodeContentWithRenderingContext
{
self = [super init];
if (self != nil) {
Expand All @@ -163,6 +167,8 @@ - (instancetype)initWithRendererAttributes:(ASTextKitAttributes)rendererAttribut
_opaque = opaque;
_bounds = bounds;
_traitCollection = traitCollection;
_willDisplayNodeContentWithRenderingContext = willDisplayNodeContentWithRenderingContext;
_didDisplayNodeContentWithRenderingContext = didDisplayNodeContentWithRenderingContext;
}
return self;
}
Expand Down Expand Up @@ -560,7 +566,9 @@ - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
contentScale:_contentsScaleForDisplay
opaque:self.isOpaque
bounds:[self threadSafeBounds]
traitCollection:self.primitiveTraitCollection];
traitCollection:self.primitiveTraitCollection
willDisplayNodeContentWithRenderingContext:self.willDisplayNodeContentWithRenderingContext
didDisplayNodeContentWithRenderingContext:self.didDisplayNodeContentWithRenderingContext];
}

+ (UIImage *)displayWithParameters:(id<NSObject>)parameters isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelled
Expand All @@ -574,12 +582,19 @@ + (UIImage *)displayWithParameters:(id<NSObject>)parameters isCancelled:(NS_NOES
UIColor *backgroundColor = drawParameter->_backgroundColor;
UIEdgeInsets textContainerInsets = drawParameter ? drawParameter->_textContainerInsets : UIEdgeInsetsZero;
ASTextKitRenderer *renderer = [drawParameter rendererForBounds:drawParameter->_bounds];
ASDisplayNodeContextModifier willDisplayNodeContentWithRenderingContext = drawParameter->_willDisplayNodeContentWithRenderingContext;
ASDisplayNodeContextModifier didDisplayNodeContentWithRenderingContext = drawParameter->_didDisplayNodeContentWithRenderingContext;

UIImage *result = ASGraphicsCreateImage(drawParameter->_traitCollection, CGSizeMake(drawParameter->_bounds.size.width, drawParameter->_bounds.size.height), drawParameter->_opaque, drawParameter->_contentScale, nil, nil, ^{
CGContextRef context = UIGraphicsGetCurrentContext();
ASDisplayNodeAssert(context, @"This is no good without a context.");

CGContextSaveGState(context);

if (context && willDisplayNodeContentWithRenderingContext) {
willDisplayNodeContentWithRenderingContext(context, drawParameter);
}

CGContextTranslateCTM(context, textContainerInsets.left, textContainerInsets.top);

// Fill background
Expand All @@ -591,6 +606,11 @@ + (UIImage *)displayWithParameters:(id<NSObject>)parameters isCancelled:(NS_NOES

// Draw text
[renderer drawInContext:context bounds:drawParameter->_bounds];

if (context && didDisplayNodeContentWithRenderingContext) {
didDisplayNodeContentWithRenderingContext(context, drawParameter);
}

CGContextRestoreGState(context);
});

Expand Down
5 changes: 1 addition & 4 deletions Source/Details/CoreGraphics+ASConvenience.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
//

#import <Foundation/Foundation.h>

#import <CoreGraphics/CoreGraphics.h>
#import <tgmath.h>

#import <AsyncDisplayKit/ASBaseDefines.h>


Expand Down Expand Up @@ -45,7 +42,7 @@ ASDISPLAYNODE_INLINE CGFloat ASCGFloatFromNumber(NSNumber *number)

ASDISPLAYNODE_INLINE BOOL CGSizeEqualToSizeWithIn(CGSize size1, CGSize size2, CGFloat delta)
{
return fabs(size1.width - size2.width) < delta && fabs(size1.height - size2.height) < delta;
return ABS(size1.width - size2.width) < delta && ABS(size1.height - size2.height) < delta;
};

NS_ASSUME_NONNULL_END
27 changes: 9 additions & 18 deletions Source/Details/_ASDisplayViewAccessiblity.mm
Original file line number Diff line number Diff line change
Expand Up @@ -311,24 +311,15 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el
}
}

@interface _ASDisplayView () {
NSArray *_accessibilityElements;
}

@end

@implementation _ASDisplayView (UIAccessibilityContainer)

#pragma mark - UIAccessibility

- (void)setAccessibilityElements:(NSArray *)accessibilityElements
{
ASDisplayNodeAssertMainThread();
// While it looks very strange to ignore the accessibilyElements param and set _accessibilityElements to nil, it is actually on purpose.
// _ASDisplayView's accessibilityElements method will always defer to the node for accessibilityElements when _accessibilityElements is
// nil. Calling setAccessibilityElements on _ASDisplayView is basically clearing the cache and forcing _ASDisplayView to ask the node
// for its accessibilityElements the next time they are requested.
_accessibilityElements = nil;
// this is a no-op. You should not be setting accessibilityElements directly on _ASDisplayView.
// if you wish to set accessibilityElements, do so in your node. UIKit will call _ASDisplayView's
// accessibilityElements which will in turn ask its node for its elements.
}

- (NSArray *)accessibilityElements
Expand All @@ -340,12 +331,12 @@ - (NSArray *)accessibilityElements
return @[];
}

// when items become hidden/visible we have to manually clear the _accessibilityElements in order to get an updated version
// Instead, let's try computing the elements every time and see how badly it affects performance.
if (_accessibilityElements == nil || ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) {
_accessibilityElements = [viewNode accessibilityElements];
}
return _accessibilityElements;
// we no longer cache accessibilityElements. When caching, in order to provide correct element when items become hidden/visible
// we had to manually clear _accessibilityElements. This seemed like a heavy burden to place on a user, and one that is also
// not immediately obvious. While recomputing accessibilityElements may be expensive, this will only affect users that have
// voice over enabled (we checked to ensure performance did not suffer by not caching for an overall user base). For those
// users with voice over on, being correct is almost certainly more important than being performant.
return [viewNode accessibilityElements];
}

@end
Expand Down
29 changes: 0 additions & 29 deletions Source/Private/ASDisplayNode+UIViewBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1137,22 +1137,6 @@ - (BOOL)_locked_insetsLayoutMarginsFromSafeArea

@implementation ASDisplayNode (UIViewBridgeAccessibility)

// Walks up the view tree to nil out all the cached accsesibilityElements. This is required when changing
// accessibility properties like accessibilityViewIsModal.
- (void)invalidateAccessibilityElements
{
// If we are not caching accessibilityElements we don't need to do anything here.
if (ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) {
return;
}

// we want to check if we are on the main thread first, since _loaded checks the layer and can only be done on main
if (ASDisplayNodeThreadIsMain() && _loaded(self)) {
self.view.accessibilityElements = nil;
[self.supernode invalidateAccessibilityElements];
}
}

- (BOOL)isAccessibilityElement
{
_bridge_prologue_read;
Expand Down Expand Up @@ -1310,13 +1294,7 @@ - (BOOL)accessibilityElementsHidden
- (void)setAccessibilityElementsHidden:(BOOL)accessibilityElementsHidden
{
_bridge_prologue_write;
BOOL oldHiddenValue = _getFromViewOnly(accessibilityElementsHidden);
_setAccessibilityToViewAndProperty(_flags.accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden);

// if we made a change, we need to clear the view's accessibilityElements cache.
if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldHiddenValue != accessibilityElementsHidden) {
[self invalidateAccessibilityElements];
}
}

- (BOOL)accessibilityViewIsModal
Expand All @@ -1328,16 +1306,9 @@ - (BOOL)accessibilityViewIsModal
- (void)setAccessibilityViewIsModal:(BOOL)accessibilityViewIsModal
{
_bridge_prologue_write;
BOOL oldAccessibilityViewIsModal = _getFromViewOnly(accessibilityViewIsModal);
_setAccessibilityToViewAndProperty(_flags.accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal);

// if we made a change, we need to clear the view's accessibilityElements cache.
if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldAccessibilityViewIsModal != accessibilityViewIsModal) {
[self invalidateAccessibilityElements];
}
}


- (BOOL)shouldGroupAccessibilityChildren
{
_bridge_prologue_read;
Expand Down
3 changes: 0 additions & 3 deletions Source/Private/ASInternalHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ ASDK_EXTERN void ASPerformBlockOnMainThread(void (^block)(void));
/// Dispatches the given block to a background queue with priority of DISPATCH_QUEUE_PRIORITY_DEFAULT if not already run on a background queue
ASDK_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT

/// For deallocation of objects on a background thread without GCD overhead / thread explosion
ASDK_EXTERN void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object);

ASDK_EXTERN CGFloat ASScreenScale(void);

ASDK_EXTERN CGSize ASFloorSizeValues(CGSize s);
Expand Down
5 changes: 0 additions & 5 deletions Source/Private/ASInternalHelpers.mm
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,6 @@ void ASPerformBlockOnBackgroundThread(void (^block)(void))
}
}

void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object)
{
[[ASDeallocQueue sharedDeallocationQueue] releaseObjectInBackground:object];
}

Class _Nullable ASGetClassFromType(const char * _Nullable type)
{
// Class types all start with @"
Expand Down
2 changes: 0 additions & 2 deletions Tests/ASConfigurationTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
ASExperimentalDispatchApply,
ASExperimentalDrawingGlobal,
ASExperimentalOptimizeDataControllerPipeline,
ASExperimentalDoNotCacheAccessibilityElements,
};

@interface ASConfigurationTests : ASTestCase <ASConfigurationDelegate>
Expand All @@ -51,7 +50,6 @@ + (NSArray *)names {
@"exp_dispatch_apply",
@"exp_drawing_global",
@"exp_optimize_data_controller_pipeline",
@"exp_do_not_cache_accessibility_elements",
];
}

Expand Down
3 changes: 0 additions & 3 deletions Tests/Common/ASTestCase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ - (void)invokeTest
@autoreleasepool {
[super invokeTest];
}

// Now that the autorelease pool is drained, drain the dealloc queue also.
[[ASDeallocQueue sharedDeallocationQueue] drain];
}

+ (ASTestCase *)currentTestCase
Expand Down
2 changes: 1 addition & 1 deletion Texture.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'Texture'
spec.version = '3.0.0-rc.2'
spec.version = '3.0.0'
spec.license = { :type => 'Apache 2', }
spec.homepage = 'http://texturegroup.org'
spec.authors = { 'Huy Nguyen' => '[email protected]', 'Garrett Moon' => '[email protected]', 'Scott Goodson' => '[email protected]', 'Michael Schneider' => '[email protected]', 'Adlai Holler' => '[email protected]' }
Expand Down
4 changes: 0 additions & 4 deletions docs/_docs/development/how-to-debug.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ Here is the collection view's `dealloc`
[self setAsyncDelegate:nil];
[self setAsyncDataSource:nil];
}

// Data controller & range controller may own a ton of nodes, let's deallocate those off-main.
ASPerformBackgroundDeallocation(&_dataController);
ASPerformBackgroundDeallocation(&_rangeController);
}
```

Expand Down
Loading

0 comments on commit 5259789

Please sign in to comment.