mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-10 16:29:55 +00:00
Add a concurrent flag to ASStackLayoutSpec that is off by default (#3148)
This commit is contained in:
parent
21953c97ef
commit
dd8cac4414
@ -59,11 +59,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@property (nonatomic, assign) ASStackLayoutJustifyContent justifyContent;
|
@property (nonatomic, assign) ASStackLayoutJustifyContent justifyContent;
|
||||||
/** Orientation of children along cross axis. Defaults to ASStackLayoutAlignItemsStretch */
|
/** Orientation of children along cross axis. Defaults to ASStackLayoutAlignItemsStretch */
|
||||||
@property (nonatomic, assign) ASStackLayoutAlignItems alignItems;
|
@property (nonatomic, assign) ASStackLayoutAlignItems alignItems;
|
||||||
//TODO documentation. Defaults to ASStackLayoutFlexWrapNoWrap
|
/** Whether children are stacked into a single or multiple lines. Defaults to single line (ASStackLayoutFlexWrapNoWrap) */
|
||||||
@property (nonatomic, assign) ASStackLayoutFlexWrap flexWrap;
|
@property (nonatomic, assign) ASStackLayoutFlexWrap flexWrap;
|
||||||
//TODO documentation. Defaults to ASStackLayoutAlignContentStart
|
/** Orientation of lines along cross axis if there are multiple lines. Defaults to ASStackLayoutAlignContentStart */
|
||||||
@property (nonatomic, assign) ASStackLayoutAlignContent alignContent;
|
@property (nonatomic, assign) ASStackLayoutAlignContent alignContent;
|
||||||
|
|
||||||
|
/** Whether this stack can dispatch to other threads, regardless of which thread it's running on */
|
||||||
|
@property (nonatomic, assign, getter=isConcurrent) BOOL concurrent;
|
||||||
|
|
||||||
- (instancetype)init;
|
- (instancetype)init;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,8 +87,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@param spacing The spacing between the children
|
@param spacing The spacing between the children
|
||||||
@param justifyContent If no children are flexible, this describes how to fill any extra space
|
@param justifyContent If no children are flexible, this describes how to fill any extra space
|
||||||
@param alignItems Orientation of the children along the cross axis
|
@param alignItems Orientation of the children along the cross axis
|
||||||
|
@param flexWrap Whether children are stacked into a single or multiple lines
|
||||||
|
@param alignContent Orientation of lines along cross axis if there are multiple lines
|
||||||
@param children ASLayoutElement children to be positioned.
|
@param children ASLayoutElement children to be positioned.
|
||||||
TODO documentation flex wrap and align content
|
|
||||||
*/
|
*/
|
||||||
+ (instancetype)stackLayoutSpecWithDirection:(ASStackLayoutDirection)direction
|
+ (instancetype)stackLayoutSpecWithDirection:(ASStackLayoutDirection)direction
|
||||||
spacing:(CGFloat)spacing
|
spacing:(CGFloat)spacing
|
||||||
|
|||||||
@ -136,7 +136,7 @@
|
|||||||
|
|
||||||
const ASStackLayoutSpecStyle style = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems, .flexWrap = _flexWrap, .alignContent = _alignContent};
|
const ASStackLayoutSpecStyle style = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems, .flexWrap = _flexWrap, .alignContent = _alignContent};
|
||||||
|
|
||||||
const auto unpositionedLayout = ASStackUnpositionedLayout::compute(stackChildren, style, constrainedSize);
|
const auto unpositionedLayout = ASStackUnpositionedLayout::compute(stackChildren, style, constrainedSize, _concurrent);
|
||||||
const auto positionedLayout = ASStackPositionedLayout::compute(unpositionedLayout, style, constrainedSize);
|
const auto positionedLayout = ASStackPositionedLayout::compute(unpositionedLayout, style, constrainedSize);
|
||||||
|
|
||||||
if (style.direction == ASStackLayoutDirectionVertical) {
|
if (style.direction == ASStackLayoutDirectionVertical) {
|
||||||
|
|||||||
@ -58,7 +58,8 @@ struct ASStackUnpositionedLayout {
|
|||||||
/** Given a set of children, computes the unpositioned layouts for those children. */
|
/** Given a set of children, computes the unpositioned layouts for those children. */
|
||||||
static ASStackUnpositionedLayout compute(const std::vector<ASStackLayoutSpecChild> &children,
|
static ASStackUnpositionedLayout compute(const std::vector<ASStackLayoutSpecChild> &children,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
const ASSizeRange &sizeRange);
|
const ASSizeRange &sizeRange,
|
||||||
|
const BOOL concurrent);
|
||||||
|
|
||||||
static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
|
static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
|
||||||
const ASStackLayoutSpecItem &l);
|
const ASStackLayoutSpecItem &l);
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
#import <AsyncDisplayKit/ASDispatch.h>
|
#import <AsyncDisplayKit/ASDispatch.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutSpecUtilities.h>
|
#import <AsyncDisplayKit/ASLayoutSpecUtilities.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutElementStylePrivate.h>
|
#import <AsyncDisplayKit/ASLayoutElementStylePrivate.h>
|
||||||
#import <AsyncDisplayKit/ASThread.h>
|
|
||||||
|
|
||||||
CGFloat const kViolationEpsilon = 0.01;
|
CGFloat const kViolationEpsilon = 0.01;
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ static ASLayout *crossChildLayout(const ASStackLayoutSpecChild &child,
|
|||||||
return layout ? : [ASLayout layoutWithLayoutElement:child.element size:{0, 0}];
|
return layout ? : [ASLayout layoutWithLayoutElement:child.element size:{0, 0}];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispatchApplyIfNeeded(size_t iterationCount, void(^work)(size_t i))
|
static void dispatchApplyIfNeeded(size_t iterationCount, BOOL forced, void(^work)(size_t i))
|
||||||
{
|
{
|
||||||
if (iterationCount == 0) {
|
if (iterationCount == 0) {
|
||||||
return;
|
return;
|
||||||
@ -80,7 +79,8 @@ static void dispatchApplyIfNeeded(size_t iterationCount, void(^work)(size_t i))
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ASDisplayNodeThreadIsMain() == NO) {
|
// TODO Once the locking situation in ASDisplayNode has improved, always dispatch if on main
|
||||||
|
if (forced == NO) {
|
||||||
for (size_t i = 0; i < iterationCount; i++) {
|
for (size_t i = 0; i < iterationCount; i++) {
|
||||||
work(i);
|
work(i);
|
||||||
}
|
}
|
||||||
@ -196,10 +196,11 @@ CGFloat ASStackUnpositionedLayout::computeCrossViolation(const CGFloat crossDime
|
|||||||
*/
|
*/
|
||||||
static void stretchItemsAlongCrossDimension(std::vector<ASStackLayoutSpecItem> &items,
|
static void stretchItemsAlongCrossDimension(std::vector<ASStackLayoutSpecItem> &items,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
|
const BOOL concurrent,
|
||||||
const CGSize parentSize,
|
const CGSize parentSize,
|
||||||
const CGFloat crossSize)
|
const CGFloat crossSize)
|
||||||
{
|
{
|
||||||
dispatchApplyIfNeeded(items.size(), ^(size_t i) {
|
dispatchApplyIfNeeded(items.size(), concurrent, ^(size_t i) {
|
||||||
auto &item = items[i];
|
auto &item = items[i];
|
||||||
const ASStackLayoutAlignItems alignItems = alignment(item.child.style.alignSelf, style.alignItems);
|
const ASStackLayoutAlignItems alignItems = alignment(item.child.style.alignSelf, style.alignItems);
|
||||||
if (alignItems == ASStackLayoutAlignItemsStretch) {
|
if (alignItems == ASStackLayoutAlignItemsStretch) {
|
||||||
@ -222,6 +223,7 @@ static void stretchItemsAlongCrossDimension(std::vector<ASStackLayoutSpecItem> &
|
|||||||
*/
|
*/
|
||||||
static void stretchLinesAlongCrossDimension(std::vector<ASStackUnpositionedLine> &lines,
|
static void stretchLinesAlongCrossDimension(std::vector<ASStackUnpositionedLine> &lines,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
|
const BOOL concurrent,
|
||||||
const ASSizeRange &sizeRange,
|
const ASSizeRange &sizeRange,
|
||||||
const CGSize parentSize)
|
const CGSize parentSize)
|
||||||
{
|
{
|
||||||
@ -239,7 +241,7 @@ static void stretchLinesAlongCrossDimension(std::vector<ASStackUnpositionedLine>
|
|||||||
line.crossSize += extraCrossSizePerLine;
|
line.crossSize += extraCrossSizePerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
stretchItemsAlongCrossDimension(line.items, style, parentSize, line.crossSize);
|
stretchItemsAlongCrossDimension(line.items, style, concurrent, parentSize, line.crossSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,10 +427,11 @@ ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(const ASStackLayoutSpecChil
|
|||||||
*/
|
*/
|
||||||
static void layoutFlexibleChildrenAtZeroSize(std::vector<ASStackLayoutSpecItem> &items,
|
static void layoutFlexibleChildrenAtZeroSize(std::vector<ASStackLayoutSpecItem> &items,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
|
const BOOL concurrent,
|
||||||
const ASSizeRange &sizeRange,
|
const ASSizeRange &sizeRange,
|
||||||
const CGSize parentSize)
|
const CGSize parentSize)
|
||||||
{
|
{
|
||||||
dispatchApplyIfNeeded(items.size(), ^(size_t i) {
|
dispatchApplyIfNeeded(items.size(), concurrent, ^(size_t i) {
|
||||||
auto &item = items[i];
|
auto &item = items[i];
|
||||||
if (isFlexibleInBothDirections(item.child)) {
|
if (isFlexibleInBothDirections(item.child)) {
|
||||||
item.layout = crossChildLayout(item.child,
|
item.layout = crossChildLayout(item.child,
|
||||||
@ -550,6 +553,7 @@ ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<ASStackLayoutSpe
|
|||||||
*/
|
*/
|
||||||
static void flexLinesAlongStackDimension(std::vector<ASStackUnpositionedLine> &lines,
|
static void flexLinesAlongStackDimension(std::vector<ASStackUnpositionedLine> &lines,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
|
const BOOL concurrent,
|
||||||
const ASSizeRange &sizeRange,
|
const ASSizeRange &sizeRange,
|
||||||
const CGSize parentSize,
|
const CGSize parentSize,
|
||||||
const BOOL useOptimizedFlexing)
|
const BOOL useOptimizedFlexing)
|
||||||
@ -567,7 +571,7 @@ static void flexLinesAlongStackDimension(std::vector<ASStackUnpositionedLine> &l
|
|||||||
if (flexFactorSum == 0) {
|
if (flexFactorSum == 0) {
|
||||||
// If optimized flexing was used then we have to clean up the unsized children and lay them out at zero size.
|
// If optimized flexing was used then we have to clean up the unsized children and lay them out at zero size.
|
||||||
if (useOptimizedFlexing) {
|
if (useOptimizedFlexing) {
|
||||||
layoutFlexibleChildrenAtZeroSize(items, style, sizeRange, parentSize);
|
layoutFlexibleChildrenAtZeroSize(items, style, concurrent, sizeRange, parentSize);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -591,7 +595,7 @@ static void flexLinesAlongStackDimension(std::vector<ASStackUnpositionedLine> &l
|
|||||||
}
|
}
|
||||||
ASDisplayNodeCAssert(firstFlexItem != -1, @"At this point there must be at least 1 flexible item");
|
ASDisplayNodeCAssert(firstFlexItem != -1, @"At this point there must be at least 1 flexible item");
|
||||||
|
|
||||||
dispatchApplyIfNeeded(items.size(), ^(size_t i) {
|
dispatchApplyIfNeeded(items.size(), concurrent, ^(size_t i) {
|
||||||
auto &item = items[i];
|
auto &item = items[i];
|
||||||
const CGFloat currentFlexAdjustment = flexAdjustment(item);
|
const CGFloat currentFlexAdjustment = flexAdjustment(item);
|
||||||
// Children are consider inflexible if they do not need to make a flex adjustment.
|
// Children are consider inflexible if they do not need to make a flex adjustment.
|
||||||
@ -655,6 +659,7 @@ static std::vector<ASStackUnpositionedLine> collectChildrenIntoLines(const std::
|
|||||||
*/
|
*/
|
||||||
static void layoutItemsAlongUnconstrainedStackDimension(std::vector<ASStackLayoutSpecItem> &items,
|
static void layoutItemsAlongUnconstrainedStackDimension(std::vector<ASStackLayoutSpecItem> &items,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
|
const BOOL concurrent,
|
||||||
const ASSizeRange &sizeRange,
|
const ASSizeRange &sizeRange,
|
||||||
const CGSize parentSize,
|
const CGSize parentSize,
|
||||||
const BOOL useOptimizedFlexing)
|
const BOOL useOptimizedFlexing)
|
||||||
@ -662,7 +667,7 @@ static void layoutItemsAlongUnconstrainedStackDimension(std::vector<ASStackLayou
|
|||||||
const CGFloat minCrossDimension = crossDimension(style.direction, sizeRange.min);
|
const CGFloat minCrossDimension = crossDimension(style.direction, sizeRange.min);
|
||||||
const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max);
|
const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max);
|
||||||
|
|
||||||
dispatchApplyIfNeeded(items.size(), ^(size_t i) {
|
dispatchApplyIfNeeded(items.size(), concurrent, ^(size_t i) {
|
||||||
auto &item = items[i];
|
auto &item = items[i];
|
||||||
if (useOptimizedFlexing && isFlexibleInBothDirections(item.child)) {
|
if (useOptimizedFlexing && isFlexibleInBothDirections(item.child)) {
|
||||||
item.layout = [ASLayout layoutWithLayoutElement:item.child.element size:{0, 0}];
|
item.layout = [ASLayout layoutWithLayoutElement:item.child.element size:{0, 0}];
|
||||||
@ -680,7 +685,8 @@ static void layoutItemsAlongUnconstrainedStackDimension(std::vector<ASStackLayou
|
|||||||
|
|
||||||
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<ASStackLayoutSpecChild> &children,
|
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<ASStackLayoutSpecChild> &children,
|
||||||
const ASStackLayoutSpecStyle &style,
|
const ASStackLayoutSpecStyle &style,
|
||||||
const ASSizeRange &sizeRange)
|
const ASSizeRange &sizeRange,
|
||||||
|
const BOOL concurrent)
|
||||||
{
|
{
|
||||||
if (children.empty()) {
|
if (children.empty()) {
|
||||||
return {};
|
return {};
|
||||||
@ -705,6 +711,7 @@ ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<A
|
|||||||
// which determines whether we must grow or shrink the flexible children.
|
// which determines whether we must grow or shrink the flexible children.
|
||||||
layoutItemsAlongUnconstrainedStackDimension(items,
|
layoutItemsAlongUnconstrainedStackDimension(items,
|
||||||
style,
|
style,
|
||||||
|
concurrent,
|
||||||
sizeRange,
|
sizeRange,
|
||||||
parentSize,
|
parentSize,
|
||||||
optimizedFlexing);
|
optimizedFlexing);
|
||||||
@ -713,14 +720,14 @@ ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<A
|
|||||||
std::vector<ASStackUnpositionedLine> lines = collectChildrenIntoLines(items, style, sizeRange);
|
std::vector<ASStackUnpositionedLine> lines = collectChildrenIntoLines(items, style, sizeRange);
|
||||||
|
|
||||||
// Resolve the flexible lengths (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths)
|
// Resolve the flexible lengths (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths)
|
||||||
flexLinesAlongStackDimension(lines, style, sizeRange, parentSize, optimizedFlexing);
|
flexLinesAlongStackDimension(lines, style, concurrent, sizeRange, parentSize, optimizedFlexing);
|
||||||
|
|
||||||
// Calculate the cross size of each flex line (https://www.w3.org/TR/css-flexbox-1/#algo-cross-line)
|
// Calculate the cross size of each flex line (https://www.w3.org/TR/css-flexbox-1/#algo-cross-line)
|
||||||
computeLinesCrossSizeAndBaseline(lines, style, sizeRange);
|
computeLinesCrossSizeAndBaseline(lines, style, sizeRange);
|
||||||
|
|
||||||
// Handle 'align-content: stretch' (https://www.w3.org/TR/css-flexbox-1/#algo-line-stretch)
|
// Handle 'align-content: stretch' (https://www.w3.org/TR/css-flexbox-1/#algo-line-stretch)
|
||||||
// Determine the used cross size of each item (https://www.w3.org/TR/css-flexbox-1/#algo-stretch)
|
// Determine the used cross size of each item (https://www.w3.org/TR/css-flexbox-1/#algo-stretch)
|
||||||
stretchLinesAlongCrossDimension(lines, style, sizeRange, parentSize);
|
stretchLinesAlongCrossDimension(lines, style, concurrent, sizeRange, parentSize);
|
||||||
|
|
||||||
// Compute stack dimension sum of each line and the whole stack
|
// Compute stack dimension sum of each line and the whole stack
|
||||||
CGFloat layoutStackDimensionSum = 0;
|
CGFloat layoutStackDimensionSum = 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user