Skip to content

Commit

Permalink
Cache more GridLayout properties to avoid lookup costs
Browse files Browse the repository at this point in the history
  • Loading branch information
hartez committed Jul 20, 2021
1 parent d076404 commit d8700be
Showing 1 changed file with 47 additions and 29 deletions.
76 changes: 47 additions & 29 deletions src/Core/src/Layouts/GridLayoutManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,72 +48,90 @@ class GridStructure

Row[] _rows { get; }
Column[] _columns { get; }
IView[] _children;
IView[] _childrenToLayOut;
Cell[] _cells { get; }

readonly Thickness _padding;
readonly double _rowSpacing;
readonly double _columnSpacing;
readonly IReadOnlyList<IGridRowDefinition> _rowDefinitions;
readonly IReadOnlyList<IGridColumnDefinition> _columnDefinitions;
readonly IReadOnlyList<IView> _gridChildren;

readonly Dictionary<SpanKey, Span> _spans = new();

public GridStructure(IGridLayout grid, double widthConstraint, double heightConstraint)
{
_grid = grid;

_gridWidthConstraint = widthConstraint;
_gridHeightConstraint = heightConstraint;

if (_grid.RowDefinitions.Count == 0)
// Cache these GridLayout properties so we don't have to keep looking them up via _grid
// (Property access via _grid may have performance implications for some SDKs.)

_padding = grid.Padding;
_columnSpacing = grid.ColumnSpacing;
_rowSpacing = grid.RowSpacing;
_rowDefinitions = grid.RowDefinitions;
_columnDefinitions = grid.ColumnDefinitions;
_gridChildren = grid.Children;

if (_rowDefinitions.Count == 0)
{
// Since no rows are specified, we'll create an implied row 0
_rows = new Row[1];
_rows[0] = new Row(new ImpliedRow());
}
else
{
_rows = new Row[_grid.RowDefinitions.Count];
_rows = new Row[_rowDefinitions.Count];

for (int n = 0; n < _grid.RowDefinitions.Count; n++)
for (int n = 0; n < _rowDefinitions.Count; n++)
{
_rows[n] = new Row(_grid.RowDefinitions[n]);
_rows[n] = new Row(_rowDefinitions[n]);
}
}

if (_grid.ColumnDefinitions.Count == 0)
if (_columnDefinitions.Count == 0)
{
// Since no columns are specified, we'll create an implied column 0
_columns = new Column[1];
_columns[0] = new Column(new ImpliedColumn());
}
else
{
_columns = new Column[_grid.ColumnDefinitions.Count];
_columns = new Column[_columnDefinitions.Count];

for (int n = 0; n < _grid.ColumnDefinitions.Count; n++)
for (int n = 0; n < _columnDefinitions.Count; n++)
{
_columns[n] = new Column(_grid.ColumnDefinitions[n]);
_columns[n] = new Column(_columnDefinitions[n]);
}
}

// We could work out the _children array (with the Collapsed items filtered out) with a Linq 1-liner
// We could work out the _childrenToLayOut array (with the Collapsed items filtered out) with a Linq 1-liner
// but doing it the hard way means we don't allocate extra enumerators, especially if we're in the
// happy path where _none_ of the children are Collapsed.
var gridChildCount = _grid.Children.Count;
var gridChildCount = _gridChildren.Count;

_children = new IView[gridChildCount];
_childrenToLayOut = new IView[gridChildCount];
int currentChild = 0;
for (int n = 0; n < gridChildCount; n++)
{
if (_grid.Children[n].Visibility != Visibility.Collapsed)
if (_gridChildren[n].Visibility != Visibility.Collapsed)
{
_children[currentChild] = _grid.Children[n];
_childrenToLayOut[currentChild] = _gridChildren[n];
currentChild += 1;
}
}

if (currentChild < gridChildCount)
{
Array.Resize(ref _children, currentChild);
Array.Resize(ref _childrenToLayOut, currentChild);
}

// We'll ignore any collapsed child views during layout
_cells = new Cell[_children.Length];
_cells = new Cell[_childrenToLayOut.Length];

InitializeCells();

Expand All @@ -122,9 +140,9 @@ public GridStructure(IGridLayout grid, double widthConstraint, double heightCons

void InitializeCells()
{
for (int n = 0; n < _children.Length; n++)
for (int n = 0; n < _childrenToLayOut.Length; n++)
{
var view = _children[n];
var view = _childrenToLayOut[n];

if (view.Visibility == Visibility.Collapsed)
{
Expand Down Expand Up @@ -188,12 +206,12 @@ public Rectangle GetCellBoundsFor(IView view)

public double GridHeight()
{
return SumDefinitions(_rows, _grid.RowSpacing) + _grid.Padding.VerticalThickness;
return SumDefinitions(_rows, _rowSpacing) + _padding.VerticalThickness;
}

public double GridWidth()
{
return SumDefinitions(_columns, _grid.ColumnSpacing) + _grid.Padding.HorizontalThickness;
return SumDefinitions(_columns, _columnSpacing) + _padding.HorizontalThickness;
}

double SumDefinitions(Definition[] definitions, double spacing)
Expand Down Expand Up @@ -237,7 +255,7 @@ void MeasureCells()

if (cell.IsColumnSpanAuto || cell.IsRowSpanAuto)
{
var measure = _children[cell.ViewIndex].Measure(availableWidth, availableHeight);
var measure = _childrenToLayOut[cell.ViewIndex].Measure(availableWidth, availableHeight);

if (cell.IsColumnSpanAuto)
{
Expand Down Expand Up @@ -297,11 +315,11 @@ void ResolveSpans()
{
if (span.IsColumn)
{
ResolveSpan(_columns, span.Start, span.Length, _grid.ColumnSpacing, span.Requested);
ResolveSpan(_columns, span.Start, span.Length, _columnSpacing, span.Requested);
}
else
{
ResolveSpan(_rows, span.Start, span.Length, _grid.RowSpacing, span.Requested);
ResolveSpan(_rows, span.Start, span.Length, _rowSpacing, span.Requested);
}
}
}
Expand Down Expand Up @@ -355,25 +373,25 @@ void ResolveSpan(Definition[] definitions, int start, int length, double spacing

double LeftEdgeOfColumn(int column)
{
double left = _grid.Padding.Left;
double left = _padding.Left;

for (int n = 0; n < column; n++)
{
left += _columns[n].Size;
left += _grid.ColumnSpacing;
left += _columnSpacing;
}

return left;
}

double TopEdgeOfRow(int row)
{
double top = _grid.Padding.Top;
double top = _padding.Top;

for (int n = 0; n < row; n++)
{
top += _rows[n].Size;
top += _grid.RowSpacing;
top += _rowSpacing;
}

return top;
Expand Down Expand Up @@ -411,7 +429,7 @@ void ResolveStars(Definition[] defs, double availableSpace, Func<Cell, bool> cel
if (cellCheck(cell)) // Check whether this cell should count toward the type of star value were measuring
{
// Update the star width if the view in this cell is bigger
starSize = Math.Max(starSize, dimension(_grid.Children[cell.ViewIndex].DesiredSize));
starSize = Math.Max(starSize, dimension(_gridChildren[cell.ViewIndex].DesiredSize));
}
}
}
Expand Down Expand Up @@ -466,7 +484,7 @@ void EnsureFinalMeasure()
width += _columns[n].Size;
}

_children[cell.ViewIndex].Measure(width, height);
_childrenToLayOut[cell.ViewIndex].Measure(width, height);
}
}
}
Expand Down

0 comments on commit d8700be

Please sign in to comment.