6
6
7
7
namespace UnityExplorer . UI . Widgets
8
8
{
9
- public struct DataViewInfo
10
- {
11
- // static
12
- public static DataViewInfo None => s_default ;
13
- private static DataViewInfo s_default = default ;
14
-
15
- public static implicit operator float ( DataViewInfo it ) => it . height ;
16
-
17
- // instance
18
- public int dataIndex , normalizedSpread ;
19
- public float height , startPosition ;
20
-
21
- public override bool Equals ( object obj )
22
- {
23
- var other = ( DataViewInfo ) obj ;
24
-
25
- return this . dataIndex == other . dataIndex
26
- && this . height == other . height
27
- && this . startPosition == other . startPosition
28
- && this . normalizedSpread == other . normalizedSpread ;
29
- }
30
-
31
- public override int GetHashCode ( ) => base . GetHashCode ( ) ;
32
- }
33
-
34
9
public class DataHeightCache < T > where T : ICell
35
10
{
36
11
private ScrollPool < T > ScrollPool { get ; }
@@ -93,11 +68,10 @@ public int GetFirstDataIndexAtPosition(float desiredHeight)
93
68
int expectedMax = expectedMin + cache . normalizedSpread - 1 ;
94
69
if ( rangeIndex < expectedMin || rangeIndex > expectedMax )
95
70
{
96
- RecalculateStartPositions ( Math . Max ( dataIndex , expectedMax ) ) ;
71
+ RecalculateStartPositions ( ScrollPool . DataSource . ItemCount - 1 ) ;
97
72
98
73
rangeIndex = GetRangeFloorOfPosition ( desiredHeight ) ;
99
74
dataIndex = rangeCache [ rangeIndex ] ;
100
- //cache = heightCache[dataIndex];
101
75
}
102
76
103
77
return dataIndex ;
@@ -125,17 +99,11 @@ private int GetRangeSpread(float startPosition, float height)
125
99
/// <summary>Append a data index to the cache with the provided height value.</summary>
126
100
public void Add ( float value )
127
101
{
128
- value = ( float ) Math . Floor ( value ) ;
129
102
value = Math . Max ( DefaultHeight , value ) ;
130
103
131
104
int spread = GetRangeSpread ( totalHeight , value ) ;
132
105
133
- heightCache . Add ( new DataViewInfo ( )
134
- {
135
- height = value ,
136
- startPosition = TotalHeight ,
137
- normalizedSpread = spread ,
138
- } ) ;
106
+ heightCache . Add ( new DataViewInfo ( heightCache . Count , value , totalHeight , spread ) ) ;
139
107
140
108
int dataIdx = heightCache . Count - 1 ;
141
109
for ( int i = 0 ; i < spread ; i ++ )
@@ -203,31 +171,31 @@ public void SetIndex(int dataIndex, float height)
203
171
int spread = GetRangeSpread ( cache . startPosition , height ) ;
204
172
205
173
// If the previous item in the range cache is not the previous data index, there is a gap.
206
- if ( dataIndex > 0 && rangeCache [ rangeIndex - 1 ] != ( dataIndex - 1 ) )
174
+ if ( rangeCache [ rangeIndex ] != dataIndex )
207
175
{
208
176
// Recalculate start positions up to this index. The gap could be anywhere before here.
209
- RecalculateStartPositions ( dataIndex + 1 ) ;
177
+ RecalculateStartPositions ( ScrollPool . DataSource . ItemCount - 1 ) ;
210
178
// Get the range index and spread again after rebuilding
211
179
rangeIndex = GetRangeCeilingOfPosition ( cache . startPosition ) ;
212
180
spread = GetRangeSpread ( cache . startPosition , height ) ;
213
181
}
214
182
215
- if ( rangeCache . Count <= rangeIndex || rangeCache [ rangeIndex ] != dataIndex )
216
- throw new Exception ( "ScrollPool data height cache is corrupt or invalid, rebuild failed !") ;
183
+ if ( rangeCache [ rangeIndex ] != dataIndex )
184
+ throw new IndexOutOfRangeException ( $ "Trying to set dataIndex { dataIndex } at rangeIndex { rangeIndex } , but cache is corrupt or invalid!") ;
217
185
218
186
if ( spread != cache . normalizedSpread )
219
187
{
220
188
int spreadDiff = spread - cache . normalizedSpread ;
221
189
cache . normalizedSpread = spread ;
222
190
223
- SetSpread ( dataIndex , rangeIndex , spreadDiff ) ;
191
+ UpdateSpread ( dataIndex , rangeIndex , spreadDiff ) ;
224
192
}
225
193
226
- // set the struct back to the array (TODO necessary?)
194
+ // set the struct back to the array
227
195
heightCache [ dataIndex ] = cache ;
228
196
}
229
197
230
- private void SetSpread ( int dataIndex , int rangeIndex , int spreadDiff )
198
+ private void UpdateSpread ( int dataIndex , int rangeIndex , int spreadDiff )
231
199
{
232
200
if ( spreadDiff > 0 )
233
201
{
@@ -244,8 +212,6 @@ private void SetSpread(int dataIndex, int rangeIndex, int spreadDiff)
244
212
rangeCache . RemoveAt ( rangeIndex ) ;
245
213
spreadDiff ++ ;
246
214
}
247
- //for (int i = 0; i < -spreadDiff; i++)
248
- // rangeCache.RemoveAt(rangeIndex);
249
215
}
250
216
}
251
217
@@ -254,24 +220,60 @@ private void RecalculateStartPositions(int toIndex)
254
220
if ( heightCache . Count <= 1 )
255
221
return ;
256
222
223
+ rangeCache . Clear ( ) ;
224
+
257
225
DataViewInfo cache ;
258
226
DataViewInfo prev = DataViewInfo . None ;
259
- for ( int i = 0 ; i <= toIndex && i < heightCache . Count ; i ++ )
227
+ for ( int idx = 0 ; idx <= toIndex && idx < heightCache . Count ; idx ++ )
260
228
{
261
- cache = heightCache [ i ] ;
229
+ cache = heightCache [ idx ] ;
262
230
263
- if ( prev != DataViewInfo . None )
231
+ if ( ! prev . Equals ( DataViewInfo . None ) )
264
232
cache . startPosition = prev . startPosition + prev . height ;
265
233
else
266
234
cache . startPosition = 0 ;
267
235
268
- var origSpread = cache . normalizedSpread ;
269
236
cache . normalizedSpread = GetRangeSpread ( cache . startPosition , cache . height ) ;
270
- if ( cache . normalizedSpread != origSpread )
271
- SetSpread ( i , GetRangeCeilingOfPosition ( cache . startPosition ) , cache . normalizedSpread - origSpread ) ;
237
+ for ( int i = 0 ; i < cache . normalizedSpread ; i ++ )
238
+ rangeCache . Add ( cache . dataIndex ) ;
239
+
240
+ heightCache [ idx ] = cache ;
272
241
273
242
prev = cache ;
274
243
}
275
244
}
245
+
246
+ public struct DataViewInfo
247
+ {
248
+ // static
249
+ public static DataViewInfo None => s_default ;
250
+ private static DataViewInfo s_default = default ;
251
+
252
+ public static implicit operator float ( DataViewInfo it ) => it . height ;
253
+
254
+ public DataViewInfo ( int index , float height , float startPos , int spread )
255
+ {
256
+ this . dataIndex = index ;
257
+ this . height = height ;
258
+ this . startPosition = startPos ;
259
+ this . normalizedSpread = spread ;
260
+ }
261
+
262
+ // instance
263
+ public int dataIndex , normalizedSpread ;
264
+ public float height , startPosition ;
265
+
266
+ public override bool Equals ( object obj )
267
+ {
268
+ var other = ( DataViewInfo ) obj ;
269
+
270
+ return this . dataIndex == other . dataIndex
271
+ && this . height == other . height
272
+ && this . startPosition == other . startPosition
273
+ && this . normalizedSpread == other . normalizedSpread ;
274
+ }
275
+
276
+ public override int GetHashCode ( ) => base . GetHashCode ( ) ;
277
+ }
276
278
}
277
279
}
0 commit comments