@@ -26,6 +26,8 @@ static readonly SharedStatic<TLayout> unmanagedLayoutStorage
2626 = SharedStatic < TLayout > . GetOrCreate < TLayout > ( ) ;
2727
2828 UnsafeList < UnmanagedRef < TClass > > classRefArray ;
29+ int rangeStart ;
30+ int rangeLength ;
2931
3032 [ NativeDisableUnsafePtrRestriction ]
3133 readonly TLayout * layoutInfo ;
@@ -44,7 +46,7 @@ static readonly SharedStatic<int> s_staticSafetyId
4446 public readonly int Length
4547 {
4648 [ MethodImpl ( AggressiveInlining ) ]
47- get => classRefArray . Length ;
49+ get => rangeLength ;
4850 }
4951
5052 public readonly bool IsCreated
@@ -56,6 +58,8 @@ public readonly bool IsCreated
5658 public void UpdateBuffer ( UnsafeList < UnmanagedRef < TClass > > classRefArray )
5759 {
5860 this . classRefArray = classRefArray ;
61+ rangeStart = 0 ;
62+ rangeLength = classRefArray . Length ;
5963#if ENABLE_UNITY_COLLECTIONS_CHECKS
6064 m_Length = classRefArray . Length ;
6165 m_MinIndex = 0 ;
@@ -66,6 +70,8 @@ public void UpdateBuffer(UnsafeList<UnmanagedRef<TClass>> classRefArray)
6670 public UnmanagedAccessArray ( UnsafeList < UnmanagedRef < TClass > > classRefArray )
6771 {
6872 this . classRefArray = classRefArray ;
73+ rangeStart = 0 ;
74+ rangeLength = classRefArray . Length ;
6975 layoutInfo = ( TLayout * ) unmanagedLayoutStorage . UnsafeDataPointer ;
7076
7177#if ENABLE_UNITY_COLLECTIONS_CHECKS
@@ -78,6 +84,31 @@ public UnmanagedAccessArray(UnsafeList<UnmanagedRef<TClass>> classRefArray)
7884#endif
7985 }
8086
87+ UnmanagedAccessArray (
88+ UnsafeList < UnmanagedRef < TClass > > classRefArray ,
89+ TLayout * layoutInfo ,
90+ int rangeStart ,
91+ int rangeLength
92+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
93+ , int length ,
94+ int minIndex ,
95+ int maxIndex ,
96+ AtomicSafetyHandle safety
97+ #endif
98+ )
99+ {
100+ this . classRefArray = classRefArray ;
101+ this . layoutInfo = layoutInfo ;
102+ this . rangeStart = rangeStart ;
103+ this . rangeLength = rangeLength ;
104+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
105+ m_Length = length ;
106+ m_MinIndex = minIndex ;
107+ m_MaxIndex = maxIndex ;
108+ m_Safety = safety ;
109+ #endif
110+ }
111+
81112 public void Dispose ( )
82113 {
83114#if ENABLE_UNITY_COLLECTIONS_CHECKS
@@ -98,11 +129,21 @@ public readonly JobHandle Dispose(JobHandle dependsOn)
98129 readonly void CheckIndexInRange ( int index )
99130 {
100131#if ENABLE_UNITY_COLLECTIONS_CHECKS
101- if ( ( uint ) index >= ( uint ) classRefArray . Length )
132+ if ( ( uint ) index >= ( uint ) rangeLength )
102133 ThrowIndexOutOfRange ( index ) ;
103134#endif
104135 }
105136
137+ [ Conditional ( "ENABLE_UNITY_COLLECTIONS_CHECKS" ) ]
138+ [ MethodImpl ( AggressiveInlining ) ]
139+ readonly void CheckAbsoluteIndexInRange ( int index )
140+ {
141+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
142+ if ( ( uint ) index >= ( uint ) classRefArray . Length )
143+ ThrowAbsoluteIndexOutOfRange ( index ) ;
144+ #endif
145+ }
146+
106147 [ Conditional ( "ENABLE_UNITY_COLLECTIONS_CHECKS" ) ]
107148 [ MethodImpl ( AggressiveInlining ) ]
108149 readonly void CheckIndexInParallelWriteRange ( int index )
@@ -125,6 +166,10 @@ readonly void CheckWriteAccess()
125166#if ENABLE_UNITY_COLLECTIONS_CHECKS
126167 [ MethodImpl ( NoInlining ) ]
127168 readonly void ThrowIndexOutOfRange ( int index )
169+ => throw new IndexOutOfRangeException ( $ "Index { index } is out of range of [0..{ rangeLength - 1 } ].") ;
170+
171+ [ MethodImpl ( NoInlining ) ]
172+ readonly void ThrowAbsoluteIndexOutOfRange ( int index )
128173 => throw new IndexOutOfRangeException ( $ "Index { index } is out of range of [0..{ m_Length - 1 } ].") ;
129174
130175 [ MethodImpl ( NoInlining ) ]
@@ -160,21 +205,48 @@ public readonly TAccessRW this[int index]
160205 [ MethodImpl ( AggressiveInlining ) ]
161206 get
162207 {
163- CheckWriteAccess ( ) ;
164208 CheckIndexInRange ( index ) ;
165- CheckIndexInParallelWriteRange ( index ) ;
209+ return AccessAt ( rangeStart + index ) ;
210+ }
211+ }
166212
167- var access = new UntypedAccess ( classRefArray [ index ] , layoutInfo ) ;
168- return UnsafeUtility . As < UntypedAccess , TAccessRW > ( ref access ) ;
213+ public readonly UnmanagedAccessArray < TClass , TLayout , TAccessRW , TAccessRO > this [ Range range ]
214+ {
215+ [ MethodImpl ( AggressiveInlining ) ]
216+ get
217+ {
218+ var ( offset , length ) = range . GetOffsetAndLength ( rangeLength ) ;
219+ return new (
220+ classRefArray ,
221+ layoutInfo ,
222+ rangeStart + offset ,
223+ length
224+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
225+ , m_Length ,
226+ m_MinIndex ,
227+ m_MaxIndex ,
228+ m_Safety
229+ #endif
230+ ) ;
169231 }
170232 }
171233
234+ [ MethodImpl ( AggressiveInlining ) ]
235+ readonly TAccessRW AccessAt ( int absoluteIndex )
236+ {
237+ CheckWriteAccess ( ) ;
238+ CheckAbsoluteIndexInRange ( absoluteIndex ) ;
239+ CheckIndexInParallelWriteRange ( absoluteIndex ) ;
240+ var access = new UntypedAccess ( classRefArray [ absoluteIndex ] , layoutInfo ) ;
241+ return UnsafeUtility . As < UntypedAccess , TAccessRW > ( ref access ) ;
242+ }
243+
172244 public readonly Enumerator GetEnumerator ( )
173245 => new ( this ) ;
174246
175247 public readonly ReadOnly AsReadOnly ( )
176248 => new (
177- classRefArray , layoutInfo
249+ classRefArray , layoutInfo , rangeStart , rangeLength
178250#if ENABLE_UNITY_COLLECTIONS_CHECKS
179251 , m_Safety
180252#endif
@@ -185,21 +257,23 @@ public struct Enumerator
185257 {
186258 readonly UnmanagedAccessArray < TClass , TLayout , TAccessRW , TAccessRO > array ;
187259 int index ;
260+ readonly int endExclusive ;
188261
189262 public Enumerator ( UnmanagedAccessArray < TClass , TLayout , TAccessRW , TAccessRO > array )
190263 {
191264 this . array = array ;
192- index = - 1 ;
265+ index = array . rangeStart - 1 ;
266+ endExclusive = array . rangeStart + array . rangeLength ;
193267
194268 array . CheckWriteAccess ( ) ;
195269
196270#if MODULE_BURST && UNITY_BURST_EXPERIMENTAL_PREFETCH_INTRINSIC && ! MEDICINE_DISABLE_UNMANAGEDACCESSARRAY_PREFETCH
197- var len = array . classRefArray . Length ;
271+ var len = array . rangeLength ;
198272 if ( len > 0 )
199273 {
200274 int count = len < PrefetchDistance ? len : PrefetchDistance ;
201275 for ( int i = 0 ; i < count ; i ++ )
202- Common . Prefetch ( ( void * ) array . classRefArray . Ptr [ i ] . Ptr , Common . ReadWrite . Write ) ;
276+ Common . Prefetch ( ( void * ) array . classRefArray . Ptr [ array . rangeStart + i ] . Ptr , Common . ReadWrite . Write ) ;
203277 }
204278#endif
205279 }
@@ -209,12 +283,12 @@ public bool MoveNext()
209283 {
210284 array . CheckWriteAccess ( ) ;
211285
212- if ( ++ index >= array . classRefArray . Length )
286+ if ( ++ index >= endExclusive )
213287 return false ;
214288
215289#if MODULE_BURST && UNITY_BURST_EXPERIMENTAL_PREFETCH_INTRINSIC && ! MEDICINE_DISABLE_UNMANAGEDACCESSARRAY_PREFETCH
216290 int prefetchOffset = index + PrefetchDistance ;
217- if ( ( uint ) prefetchOffset < ( uint ) array . classRefArray . Length )
291+ if ( ( uint ) prefetchOffset < ( uint ) endExclusive )
218292 Common . Prefetch ( ( void * ) array . classRefArray . Ptr [ prefetchOffset ] . Ptr , Common . ReadWrite . Write ) ;
219293#endif
220294
@@ -224,7 +298,7 @@ public bool MoveNext()
224298 public TAccessRW Current
225299 {
226300 [ MethodImpl ( AggressiveInlining ) ]
227- get => array [ index ] ;
301+ get => array . AccessAt ( index ) ;
228302 }
229303 }
230304
@@ -233,6 +307,8 @@ public TAccessRW Current
233307 public readonly struct ReadOnly
234308 {
235309 readonly UnsafeList < UnmanagedRef < TClass > > classRefArray ;
310+ readonly int rangeStart ;
311+ readonly int rangeLength ;
236312
237313 [ NativeDisableUnsafePtrRestriction ]
238314 readonly TLayout * layoutInfo ;
@@ -244,7 +320,7 @@ public readonly struct ReadOnly
244320 public int Length
245321 {
246322 [ MethodImpl ( AggressiveInlining ) ]
247- get => classRefArray . Length ;
323+ get => rangeLength ;
248324 }
249325
250326 public bool IsCreated
@@ -254,14 +330,19 @@ public bool IsCreated
254330 }
255331
256332 public ReadOnly (
257- UnsafeList < UnmanagedRef < TClass > > classRefArray , TLayout * layoutInfo
333+ UnsafeList < UnmanagedRef < TClass > > classRefArray ,
334+ TLayout * layoutInfo ,
335+ int rangeStart ,
336+ int rangeLength
258337#if ENABLE_UNITY_COLLECTIONS_CHECKS
259338 , AtomicSafetyHandle safety
260339#endif
261340 )
262341 {
263342 this . classRefArray = classRefArray ;
264343 this . layoutInfo = layoutInfo ;
344+ this . rangeStart = rangeStart ;
345+ this . rangeLength = rangeLength ;
265346#if ENABLE_UNITY_COLLECTIONS_CHECKS
266347 m_Safety = safety ;
267348#endif
@@ -272,11 +353,21 @@ public ReadOnly(
272353 void CheckIndexInRange ( int index )
273354 {
274355#if ENABLE_UNITY_COLLECTIONS_CHECKS
275- if ( ( uint ) index >= ( uint ) classRefArray . Length )
356+ if ( ( uint ) index >= ( uint ) rangeLength )
276357 ThrowIndexOutOfRange ( index ) ;
277358#endif
278359 }
279360
361+ [ Conditional ( "ENABLE_UNITY_COLLECTIONS_CHECKS" ) ]
362+ [ MethodImpl ( AggressiveInlining ) ]
363+ void CheckAbsoluteIndexInRange ( int index )
364+ {
365+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
366+ if ( ( uint ) index >= ( uint ) classRefArray . Length )
367+ ThrowAbsoluteIndexOutOfRange ( index ) ;
368+ #endif
369+ }
370+
280371 [ Conditional ( "ENABLE_UNITY_COLLECTIONS_CHECKS" ) ]
281372 [ MethodImpl ( AggressiveInlining ) ]
282373 void CheckReadAccess ( )
@@ -289,6 +380,10 @@ void CheckReadAccess()
289380#if ENABLE_UNITY_COLLECTIONS_CHECKS
290381 [ MethodImpl ( NoInlining ) ]
291382 void ThrowIndexOutOfRange ( int index )
383+ => throw new IndexOutOfRangeException ( $ "Index { index } is out of range of [0..{ rangeLength - 1 } ].") ;
384+
385+ [ MethodImpl ( NoInlining ) ]
386+ void ThrowAbsoluteIndexOutOfRange ( int index )
292387 => throw new IndexOutOfRangeException ( $ "Index { index } is out of range of [0..{ classRefArray . Length - 1 } ].") ;
293388#endif
294389
@@ -297,14 +392,38 @@ public TAccessRO this[int index]
297392 [ MethodImpl ( AggressiveInlining ) ]
298393 get
299394 {
300- CheckReadAccess ( ) ;
301395 CheckIndexInRange ( index ) ;
396+ return AccessAt ( rangeStart + index ) ;
397+ }
398+ }
302399
303- var access = new UntypedAccess ( classRefArray [ index ] , layoutInfo ) ;
304- return UnsafeUtility . As < UntypedAccess , TAccessRO > ( ref access ) ;
400+ public ReadOnly this [ Range range ]
401+ {
402+ [ MethodImpl ( AggressiveInlining ) ]
403+ get
404+ {
405+ var ( offset , length ) = range . GetOffsetAndLength ( rangeLength ) ;
406+ return new (
407+ classRefArray ,
408+ layoutInfo ,
409+ rangeStart + offset ,
410+ length
411+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
412+ , m_Safety
413+ #endif
414+ ) ;
305415 }
306416 }
307417
418+ [ MethodImpl ( AggressiveInlining ) ]
419+ TAccessRO AccessAt ( int absoluteIndex )
420+ {
421+ CheckReadAccess ( ) ;
422+ CheckAbsoluteIndexInRange ( absoluteIndex ) ;
423+ var access = new UntypedAccess ( classRefArray [ absoluteIndex ] , layoutInfo ) ;
424+ return UnsafeUtility . As < UntypedAccess , TAccessRO > ( ref access ) ;
425+ }
426+
308427 public Enumerator GetEnumerator ( )
309428 => new ( this ) ;
310429
@@ -314,19 +433,21 @@ public struct Enumerator
314433 {
315434 readonly ReadOnly array ;
316435 int index ;
436+ readonly int endExclusive ;
317437
318438 public Enumerator ( in ReadOnly array )
319439 {
320440 this . array = array ;
321- index = - 1 ;
441+ index = array . rangeStart - 1 ;
442+ endExclusive = array . rangeStart + array . rangeLength ;
322443
323444#if MODULE_BURST && UNITY_BURST_EXPERIMENTAL_PREFETCH_INTRINSIC && ! MEDICINE_DISABLE_UNMANAGEDACCESSARRAY_PREFETCH
324- var len = array . Length ;
445+ var len = array . rangeLength ;
325446 if ( len > 0 )
326447 {
327448 int count = len < PrefetchDistance ? len : PrefetchDistance ;
328449 for ( int i = 0 ; i < count ; i ++ )
329- Common . Prefetch ( ( void * ) array . classRefArray . Ptr [ i ] . Ptr , Common . ReadWrite . Read ) ;
450+ Common . Prefetch ( ( void * ) array . classRefArray . Ptr [ array . rangeStart + i ] . Ptr , Common . ReadWrite . Read ) ;
330451 }
331452#endif
332453 }
@@ -336,12 +457,12 @@ public bool MoveNext()
336457 {
337458 array . CheckReadAccess ( ) ;
338459
339- if ( ++ index >= array . classRefArray . Length )
460+ if ( ++ index >= endExclusive )
340461 return false ;
341462
342463#if MODULE_BURST && UNITY_BURST_EXPERIMENTAL_PREFETCH_INTRINSIC && ! MEDICINE_DISABLE_UNMANAGEDACCESSARRAY_PREFETCH
343464 int prefetchOffset = index + PrefetchDistance ;
344- if ( ( uint ) prefetchOffset < ( uint ) array . classRefArray . Length )
465+ if ( ( uint ) prefetchOffset < ( uint ) endExclusive )
345466 Common . Prefetch ( ( void * ) array . classRefArray . Ptr [ prefetchOffset ] . Ptr , Common . ReadWrite . Read ) ;
346467#endif
347468
@@ -351,9 +472,9 @@ public bool MoveNext()
351472 public TAccessRO Current
352473 {
353474 [ MethodImpl ( AggressiveInlining ) ]
354- get => array [ index ] ;
475+ get => array . AccessAt ( index ) ;
355476 }
356477 }
357478 }
358479 }
359- }
480+ }
0 commit comments