mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-04 11:50:38 +00:00
Copy yogaChildren in accessor method. Avoid using accessor method internally (#1283)
* Copy yogaChildren in accessor method. Avoid using accessor method internally. * Further improvements
This commit is contained in:
parent
4982c84640
commit
ab0a00c21c
@ -188,8 +188,7 @@ AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullab
|
||||
|
||||
@interface ASDisplayNode (Yoga)
|
||||
|
||||
// TODO: Make this and yogaCalculatedLayout atomic (lock).
|
||||
@property (nullable, nonatomic) NSArray *yogaChildren;
|
||||
@property (copy) NSArray *yogaChildren;
|
||||
|
||||
- (void)addYogaChild:(ASDisplayNode *)child;
|
||||
- (void)removeYogaChild:(ASDisplayNode *)child;
|
||||
@ -198,6 +197,7 @@ AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullab
|
||||
- (void)semanticContentAttributeDidChange:(UISemanticContentAttribute)attribute;
|
||||
|
||||
@property BOOL yogaLayoutInProgress;
|
||||
// TODO: Make this atomic (lock).
|
||||
@property (nullable, nonatomic) ASLayout *yogaCalculatedLayout;
|
||||
|
||||
// Will walk up the Yoga tree and returns the root node
|
||||
|
@ -48,32 +48,43 @@
|
||||
for (ASDisplayNode *child in [_yogaChildren copy]) {
|
||||
// Make sure to un-associate the YGNodeRef tree before replacing _yogaChildren
|
||||
// If this becomes a performance bottleneck, it can be optimized by not doing the NSArray removals here.
|
||||
[self removeYogaChild:child];
|
||||
[self _locked_removeYogaChild:child];
|
||||
}
|
||||
_yogaChildren = nil;
|
||||
for (ASDisplayNode *child in yogaChildren) {
|
||||
[self addYogaChild:child];
|
||||
[self _locked_addYogaChild:child];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)yogaChildren
|
||||
{
|
||||
return _yogaChildren;
|
||||
ASLockScope(self.yogaRoot);
|
||||
return [_yogaChildren copy] ?: @[];
|
||||
}
|
||||
|
||||
- (void)addYogaChild:(ASDisplayNode *)child
|
||||
{
|
||||
ASLockScope(self.yogaRoot);
|
||||
[self _locked_addYogaChild:child];
|
||||
}
|
||||
|
||||
- (void)_locked_addYogaChild:(ASDisplayNode *)child
|
||||
{
|
||||
[self insertYogaChild:child atIndex:_yogaChildren.count];
|
||||
}
|
||||
|
||||
- (void)removeYogaChild:(ASDisplayNode *)child
|
||||
{
|
||||
ASLockScope(self.yogaRoot);
|
||||
[self _locked_removeYogaChild:child];
|
||||
}
|
||||
|
||||
- (void)_locked_removeYogaChild:(ASDisplayNode *)child
|
||||
{
|
||||
if (child == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[_yogaChildren removeObjectIdenticalTo:child];
|
||||
|
||||
// YGNodeRef removal is done in setParent:
|
||||
@ -83,6 +94,11 @@
|
||||
- (void)insertYogaChild:(ASDisplayNode *)child atIndex:(NSUInteger)index
|
||||
{
|
||||
ASLockScope(self.yogaRoot);
|
||||
[self _locked_insertYogaChild:child atIndex:index];
|
||||
}
|
||||
|
||||
- (void)_locked_insertYogaChild:(ASDisplayNode *)child atIndex:(NSUInteger)index
|
||||
{
|
||||
if (child == nil) {
|
||||
return;
|
||||
}
|
||||
@ -91,7 +107,7 @@
|
||||
}
|
||||
|
||||
// Clean up state in case this child had another parent.
|
||||
[self removeYogaChild:child];
|
||||
[self _locked_removeYogaChild:child];
|
||||
|
||||
[_yogaChildren insertObject:child atIndex:index];
|
||||
|
||||
@ -99,6 +115,8 @@
|
||||
child.yogaParent = self;
|
||||
}
|
||||
|
||||
#pragma mark - Subclass Hooks
|
||||
|
||||
- (void)semanticContentAttributeDidChange:(UISemanticContentAttribute)attribute
|
||||
{
|
||||
UIUserInterfaceLayoutDirection layoutDirection =
|
||||
@ -168,8 +186,9 @@
|
||||
|
||||
YGNodeRef yogaNode = self.style.yogaNode;
|
||||
uint32_t childCount = YGNodeGetChildCount(yogaNode);
|
||||
ASDisplayNodeAssert(childCount == self.yogaChildren.count,
|
||||
@"Yoga tree should always be in sync with .yogaNodes array! %@", self.yogaChildren);
|
||||
ASDisplayNodeAssert(childCount == _yogaChildren.count,
|
||||
@"Yoga tree should always be in sync with .yogaNodes array! %@",
|
||||
_yogaChildren);
|
||||
|
||||
ASLayout *rawSublayouts[childCount];
|
||||
int i = 0;
|
||||
|
@ -49,7 +49,9 @@ void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode *node, void(^block)
|
||||
return;
|
||||
}
|
||||
block(node);
|
||||
for (ASDisplayNode *child in [node yogaChildren]) {
|
||||
// We use the accessor here despite the copy, because the block may modify the yoga tree e.g.
|
||||
// replacing a node.
|
||||
for (ASDisplayNode *child in node.yogaChildren) {
|
||||
ASDisplayNodePerformBlockOnEveryYogaChild(child, block);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user