Add locking for ASInterfaceState. Misc. cleanup.

This commit is contained in:
Scott Goodson
2015-11-29 14:57:43 -08:00
parent fb9f37b293
commit 254f55b758
5 changed files with 68 additions and 65 deletions

View File

@@ -379,11 +379,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
return YES;
}
- (void)__exitedHierarchy
{
}
- (UIView *)_viewToLoad
{
UIView *view;
@@ -787,55 +782,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
return transform;
}
static inline BOOL _ASDisplayNodeIsAncestorOfDisplayNode(ASDisplayNode *possibleAncestor, ASDisplayNode *possibleDescendent)
{
ASDisplayNode *supernode = possibleDescendent;
while (supernode) {
if (supernode == possibleAncestor) {
return YES;
}
supernode = supernode.supernode;
}
return NO;
}
/**
* NOTE: It is an error to try to convert between nodes which do not share a common ancestor. This behavior is
* disallowed in UIKit documentation and the behavior is left undefined. The output does not have a rigorously defined
* failure mode (i.e. returning CGPointZero or returning the point exactly as passed in). Rather than track the internal
* undefined and undocumented behavior of UIKit in ASDisplayNode, this operation is defined to be incorrect in all
* circumstances and must be fixed wherever encountered.
*/
static inline ASDisplayNode *_ASDisplayNodeFindClosestCommonAncestor(ASDisplayNode *node1, ASDisplayNode *node2)
{
ASDisplayNode *possibleAncestor = node1;
while (possibleAncestor) {
if (_ASDisplayNodeIsAncestorOfDisplayNode(possibleAncestor, node2)) {
break;
}
possibleAncestor = possibleAncestor.supernode;
}
ASDisplayNodeCAssertNotNil(possibleAncestor, @"Could not find a common ancestor between node1: %@ and node2: %@", node1, node2);
return possibleAncestor;
}
static inline ASDisplayNode *_getRootNode(ASDisplayNode *node)
{
// node <- supernode on each loop
// previous <- node on each loop where node is not nil
// previous is the final non-nil value of supernode, i.e. the root node
ASDisplayNode *previousNode = node;
while ((node = [node supernode])) {
previousNode = node;
}
return previousNode;
}
static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNode *referenceNode, ASDisplayNode *targetNode)
{
ASDisplayNode *ancestor = _ASDisplayNodeFindClosestCommonAncestor(referenceNode, targetNode);
ASDisplayNode *ancestor = ASDisplayNodeFindClosestCommonAncestor(referenceNode, targetNode);
// Transform into global (away from reference coordinate space)
CATransform3D transformToGlobal = [referenceNode _transformToAncestor:ancestor];
@@ -850,7 +799,7 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
{
ASDisplayNodeAssertThreadAffinity(self);
// Get root node of the accessible node hierarchy, if node not specified
node = node ? node : _getRootNode(self);
node = node ? node : ASDisplayNodeUltimateParentOfNode(self);
// Calculate transform to map points between coordinate spaces
CATransform3D nodeTransform = _calculateTransformFromReferenceToTarget(node, self);
@@ -865,7 +814,7 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
{
ASDisplayNodeAssertThreadAffinity(self);
// Get root node of the accessible node hierarchy, if node not specified
node = node ? node : _getRootNode(self);
node = node ? node : ASDisplayNodeUltimateParentOfNode(self);
// Calculate transform to map points between coordinate spaces
CATransform3D nodeTransform = _calculateTransformFromReferenceToTarget(self, node);
@@ -880,7 +829,7 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
{
ASDisplayNodeAssertThreadAffinity(self);
// Get root node of the accessible node hierarchy, if node not specified
node = node ? node : _getRootNode(self);
node = node ? node : ASDisplayNodeUltimateParentOfNode(self);
// Calculate transform to map points between coordinate spaces
CATransform3D nodeTransform = _calculateTransformFromReferenceToTarget(node, self);
@@ -895,7 +844,7 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
{
ASDisplayNodeAssertThreadAffinity(self);
// Get root node of the accessible node hierarchy, if node not specified
node = node ? node : _getRootNode(self);
node = node ? node : ASDisplayNodeUltimateParentOfNode(self);
// Calculate transform to map points between coordinate spaces
CATransform3D nodeTransform = _calculateTransformFromReferenceToTarget(self, node);
@@ -1614,6 +1563,7 @@ void recursivelyEnsureDisplayForLayer(CALayer *layer)
- (void)__didLoad
{
ASDN::MutexLocker l(_propertyLock);
if (_nodeLoadedBlock) {
_nodeLoadedBlock(self);
_nodeLoadedBlock = nil;
@@ -1638,8 +1588,6 @@ void recursivelyEnsureDisplayForLayer(CALayer *layer)
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(_flags.isExitingHierarchy, @"You should never call -didExitHierarchy directly. Appearance is automatically managed by ASDisplayNode");
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
[self __exitedHierarchy];
}
- (void)clearContents
@@ -1689,11 +1637,13 @@ void recursivelyEnsureDisplayForLayer(CALayer *layer)
- (ASInterfaceState)interfaceState
{
ASDN::MutexLocker l(_propertyLock);
return _interfaceState;
}
- (void)setInterfaceState:(ASInterfaceState)interfaceState
{
ASDN::MutexLocker l(_propertyLock);
if (interfaceState != _interfaceState) {
if ((interfaceState & ASInterfaceStateMeasureLayout) != (_interfaceState & ASInterfaceStateMeasureLayout)) {
// Trigger asynchronous measurement if it is not already cached or being calculated.