Some clean up

This commit is contained in:
Adlai Holler
2016-01-07 23:39:11 -08:00
parent ea304f7f37
commit b5b5f9f559
5 changed files with 34 additions and 31 deletions

View File

@@ -277,6 +277,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
_contentsScaleForDisplay = ASScreenScale(); _contentsScaleForDisplay = ASScreenScale();
_displaySentinel = [[ASSentinel alloc] init]; _displaySentinel = [[ASSentinel alloc] init];
_preferredFrameSize = CGSizeZero; _preferredFrameSize = CGSizeZero;
_pendingViewState = [_ASPendingState new];
} }
- (id)init - (id)init
@@ -2358,15 +2359,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
#pragma mark - Pending View State #pragma mark - Pending View State
- (_ASPendingState *)pendingViewState
{
if (!_pendingViewState) {
_pendingViewState = [[_ASPendingState alloc] init];
ASDisplayNodeAssertNotNil(_pendingViewState, @"should have created a pendingViewState");
}
return _pendingViewState;
}
- (void)_applyPendingStateToViewOrLayer - (void)_applyPendingStateToViewOrLayer
{ {

View File

@@ -16,6 +16,7 @@
#import "ASDisplayNode+FrameworkPrivate.h" #import "ASDisplayNode+FrameworkPrivate.h"
#import "ASDisplayNode+Beta.h" #import "ASDisplayNode+Beta.h"
#import "ASEqualityHelpers.h" #import "ASEqualityHelpers.h"
#import "ASPendingStateController.h"
/** /**
* The following macros are conveniences to help in the common tasks related to the bridging that ASDisplayNode does to UIView and CALayer. * The following macros are conveniences to help in the common tasks related to the bridging that ASDisplayNode does to UIView and CALayer.
@@ -42,11 +43,25 @@
#define _bridge_prologue () #define _bridge_prologue ()
#endif #endif
#define _setToViewOrLayer(layerProperty, layerValueExpr, viewAndPendingViewStateProperty, viewAndPendingViewStateExpr) __loaded ? \ /// Returns YES if the property set should be applied to view/layer immediately.
(_view ? _view.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr) : _layer.layerProperty = (layerValueExpr))\ ASDISPLAYNODE_INLINE BOOL ASDisplayNodeMarkDirtyIfNeeded(ASDisplayNode *node) {
: self.pendingViewState.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr) if (NSThread.isMainThread) {
return node.nodeLoaded;
} else {
if (node.nodeLoaded && !node->_pendingViewState.hasChanges) {
[ASPendingStateController.sharedInstance registerNode:node];
}
return NO;
}
};
#define _setToViewOnly(viewAndPendingViewStateProperty, viewAndPendingViewStateExpr) __loaded ? _view.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr) : self.pendingViewState.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr) #define _setToViewOrLayer(layerProperty, layerValueExpr, viewAndPendingViewStateProperty, viewAndPendingViewStateExpr) BOOL shouldApply = ASDisplayNodeMarkDirtyIfNeeded(self); \
_pendingViewState.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr); \
if (shouldApply) { (_view ? _view.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr) : _layer.layerProperty = (layerValueExpr)); }
#define _setToViewOnly(viewAndPendingViewStateProperty, viewAndPendingViewStateExpr) BOOL shouldApply = ASDisplayNodeMarkDirtyIfNeeded(self); \
_pendingViewState.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr); \
if (shouldApply) { _view.viewAndPendingViewStateProperty = (viewAndPendingViewStateExpr); }
#define _getFromPendingViewState(viewAndPendingViewStateProperty) _pendingViewState.viewAndPendingViewStateProperty #define _getFromPendingViewState(viewAndPendingViewStateProperty) _pendingViewState.viewAndPendingViewStateProperty
@@ -217,7 +232,6 @@
// Checking if the transform is identity is expensive, so disable when unnecessary. We have assertions on in Release, so DEBUG is the only way I know of. // Checking if the transform is identity is expensive, so disable when unnecessary. We have assertions on in Release, so DEBUG is the only way I know of.
ASDisplayNodeAssert(CATransform3DIsIdentity(self.transform), @"-[ASDisplayNode setFrame:] - self.transform must be identity in order to set the frame property. (From Apple's UIView documentation: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.)"); ASDisplayNodeAssert(CATransform3DIsIdentity(self.transform), @"-[ASDisplayNode setFrame:] - self.transform must be identity in order to set the frame property. (From Apple's UIView documentation: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.)");
#endif #endif
_setToViewOnly(frame, rect); _setToViewOnly(frame, rect);
} else { } else {
// This is by far the common case / hot path. // This is by far the common case / hot path.
@@ -307,16 +321,10 @@
- (void)setOpaque:(BOOL)newOpaque - (void)setOpaque:(BOOL)newOpaque
{ {
BOOL prevOpaque = self.opaque;
_bridge_prologue; _bridge_prologue;
if (prevOpaque != newOpaque) { _setToViewOrLayer(opaque, newOpaque, opaque, newOpaque);
[self setNeedsDisplay];
}
if (NSThread.isMainThread) { // TODO: Mark as needs display if value changed?
_setToLayer(opaque, newOpaque);
}
} }
- (BOOL)isUserInteractionEnabled - (BOOL)isUserInteractionEnabled

View File

@@ -50,6 +50,9 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
@interface ASDisplayNode () @interface ASDisplayNode ()
{ {
@package
_ASPendingState *_pendingViewState;
@protected @protected
// Protects access to _view, _layer, _pendingViewState, _subnodes, _supernode, and other properties which are accessed from multiple threads. // Protects access to _view, _layer, _pendingViewState, _subnodes, _supernode, and other properties which are accessed from multiple threads.
ASDN::RecursiveMutex _propertyLock; ASDN::RecursiveMutex _propertyLock;
@@ -92,8 +95,6 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
// keeps track of nodes/subnodes that have not finished display, used with placeholders // keeps track of nodes/subnodes that have not finished display, used with placeholders
NSMutableSet *_pendingDisplayNodes; NSMutableSet *_pendingDisplayNodes;
_ASPendingState *_pendingViewState;
struct ASDisplayNodeFlags { struct ASDisplayNodeFlags {
// public properties // public properties

View File

@@ -10,6 +10,7 @@
#import "ASThread.h" #import "ASThread.h"
#import "ASWeakSet.h" #import "ASWeakSet.h"
#import "ASDisplayNode.h" #import "ASDisplayNode.h"
#import "ASAssert.h"
@interface ASPendingStateController() @interface ASPendingStateController()
{ {
@@ -56,6 +57,7 @@
- (void)registerNode:(ASDisplayNode *)node - (void)registerNode:(ASDisplayNode *)node
{ {
ASDisplayNodeAssert(node.nodeLoaded, @"Expected display node to be loaded before it was registered with ASPendingStateController. Node: %@", node);
ASDN::MutexLocker l(_lock); ASDN::MutexLocker l(_lock);
[_dirtyNodes addObject:node]; [_dirtyNodes addObject:node];

View File

@@ -425,6 +425,12 @@ for (ASDisplayNode *n in @[ nodes ]) {\
- (void)checkSimpleBridgePropertiesSetPropagate:(BOOL)isLayerBacked - (void)checkSimpleBridgePropertiesSetPropagate:(BOOL)isLayerBacked
{ {
/// The first node we instantiate must be created on the main thread
/// in order to read ASScreenScale() safely. We create this throwaway
/// node so that running this test first in the suite
/// doesn't cause a deadlock.
[ASDisplayNode new];
__block ASDisplayNode *node = nil; __block ASDisplayNode *node = nil;
[self executeOffThread:^{ [self executeOffThread:^{
@@ -484,13 +490,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
[self checkValuesMatchSetValues:node isLayerBacked:isLayerBacked]; [self checkValuesMatchSetValues:node isLayerBacked:isLayerBacked];
// As a final sanity check, change a value on the realized view and ensure it is fetched through the node. // TODO: Handle backwards propagation i.e. from view/layer to node.
if (isLayerBacked) {
node.layer.hidden = NO;
} else {
node.view.hidden = NO;
}
XCTAssertEqual(NO, node.hidden, @"After the view is realized, the node should delegate properties to the view.");
} }
// Set each of the simple bridged UIView properties to a non-default value off-thread, then // Set each of the simple bridged UIView properties to a non-default value off-thread, then