2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
// See the LICENSE file in the project root for more information.
4
4
5
- using System ;
6
- using System . Collections . Generic ;
7
- using System . Linq ;
8
- using System . Text ;
9
- using System . Threading . Tasks ;
5
+ using System . Collections ;
6
+ using System . Drawing ;
7
+ using Microsoft . Toolkit . Diagnostics ;
10
8
11
9
namespace Microsoft . Toolkit . Uwp . UI . Controls
12
10
{
@@ -16,23 +14,81 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
16
14
/// <see cref="UniformGrid.GetFreeSpot"/> iterator.
17
15
/// This is used so we can better isolate our logic and make it easier to test.
18
16
/// </summary>
19
- internal class TakenSpotsReferenceHolder
17
+ internal sealed class TakenSpotsReferenceHolder
20
18
{
21
19
/// <summary>
22
- /// Gets or sets the array to hold taken spots.
23
- /// True value indicates an item in the layout is fixed to that position.
24
- /// False values indicate free openings where an item can be placed.
20
+ /// The <see cref="BitArray"/> instance used to efficiently track empty spots.
25
21
/// </summary>
26
- public bool [ , ] SpotsTaken { get ; set ; }
22
+ private readonly BitArray spotsTaken ;
27
23
24
+ /// <summary>
25
+ /// Initializes a new instance of the <see cref="TakenSpotsReferenceHolder"/> class.
26
+ /// </summary>
27
+ /// <param name="rows">The number of rows to track.</param>
28
+ /// <param name="columns">The number of columns to track.</param>
28
29
public TakenSpotsReferenceHolder ( int rows , int columns )
29
30
{
30
- SpotsTaken = new bool [ rows , columns ] ;
31
+ Guard . IsGreaterThanOrEqualTo ( rows , 0 , nameof ( rows ) ) ;
32
+ Guard . IsGreaterThanOrEqualTo ( columns , 0 , nameof ( columns ) ) ;
33
+
34
+ Height = rows ;
35
+ Width = columns ;
36
+
37
+ this . spotsTaken = new BitArray ( rows * columns ) ;
38
+ }
39
+
40
+ /// <summary>
41
+ /// Gets the height of the grid to monitor.
42
+ /// </summary>
43
+ public int Height { get ; }
44
+
45
+ /// <summary>
46
+ /// Gets the width of the grid to monitor.
47
+ /// </summary>
48
+ public int Width { get ; }
49
+
50
+ /// <summary>
51
+ /// Gets or sets the value of a specified grid cell.
52
+ /// </summary>
53
+ /// <param name="i">The vertical offset.</param>
54
+ /// <param name="j">The horizontal offset.</param>
55
+ public bool this [ int i , int j ]
56
+ {
57
+ get => this . spotsTaken [ ( i * Width ) + j ] ;
58
+ set => this . spotsTaken [ ( i * Width ) + j ] = value ;
59
+ }
60
+
61
+ /// <summary>
62
+ /// Fills the specified area in the current grid with a given value.
63
+ /// If invalid coordinates are given, they will simply be ignored and no exception will be thrown.
64
+ /// </summary>
65
+ /// <param name="value">The value to fill the target area with.</param>
66
+ /// <param name="row">The row to start on (inclusive, 0-based index).</param>
67
+ /// <param name="column">The column to start on (inclusive, 0-based index).</param>
68
+ /// <param name="width">The positive width of area to fill.</param>
69
+ /// <param name="height">The positive height of area to fill.</param>
70
+ public void Fill ( bool value , int row , int column , int width , int height )
71
+ {
72
+ Rectangle bounds = new Rectangle ( 0 , 0 , Width , Height ) ;
73
+
74
+ // Precompute bounds to skip branching in main loop
75
+ bounds . Intersect ( new Rectangle ( column , row , width , height ) ) ;
76
+
77
+ for ( int i = bounds . Top ; i < bounds . Bottom ; i ++ )
78
+ {
79
+ for ( int j = bounds . Left ; j < bounds . Right ; j ++ )
80
+ {
81
+ this [ i , j ] = value ;
82
+ }
83
+ }
31
84
}
32
85
33
- public TakenSpotsReferenceHolder ( bool [ , ] array )
86
+ /// <summary>
87
+ /// Resets the current reference holder.
88
+ /// </summary>
89
+ public void Reset ( )
34
90
{
35
- SpotsTaken = array ;
91
+ this . spotsTaken . SetAll ( false ) ;
36
92
}
37
93
}
38
94
}
0 commit comments