2
2
using System . Collections ;
3
3
using System . Collections . Generic ;
4
4
using System . Collections . ObjectModel ;
5
- using UnityEngine . UIElements ;
5
+ using System . Linq ;
6
6
7
7
// ReSharper disable once CheckNamespace
8
8
@@ -275,16 +275,26 @@ public virtual bool Remove(TKey key)
275
275
276
276
if ( ObservableUpdateFlag != ObservableUpdateFlag . UpdateOnly && _keyUpdateActions . TryGetValue ( key , out var actions ) )
277
277
{
278
- for ( var i = 0 ; i < actions . Count ; i ++ )
278
+ for ( var i = actions . Count - 1 ; i > - 1 ; i -- )
279
279
{
280
- actions [ i ] ( key , value , default , ObservableUpdateType . Removed ) ;
280
+ var action = actions [ i ] ;
281
+
282
+ action ( key , value , default , ObservableUpdateType . Removed ) ;
283
+
284
+ // Shift the index if an action was unsubscribed
285
+ i = AdjustIndex ( i , action , actions ) ;
281
286
}
282
287
}
283
288
if ( ObservableUpdateFlag != ObservableUpdateFlag . KeyUpdateOnly )
284
289
{
285
- for ( var i = 0 ; i < _updateActions . Count ; i ++ )
290
+ for ( var i = _updateActions . Count - 1 ; i > - 1 ; i -- )
286
291
{
287
- _updateActions [ i ] ( key , value , default , ObservableUpdateType . Removed ) ;
292
+ var action = _updateActions [ i ] ;
293
+
294
+ action ( key , value , default , ObservableUpdateType . Removed ) ;
295
+
296
+ // Shift the index if an action was unsubscribed
297
+ i = AdjustIndex ( i , action , _updateActions ) ;
288
298
}
289
299
}
290
300
@@ -294,31 +304,34 @@ public virtual bool Remove(TKey key)
294
304
/// <inheritdoc />
295
305
public virtual void Clear ( )
296
306
{
297
- var dictionary = new Dictionary < TKey , TValue > ( Dictionary ) ;
298
-
299
- Dictionary . Clear ( ) ;
300
-
301
307
if ( ObservableUpdateFlag != ObservableUpdateFlag . UpdateOnly )
302
308
{
303
- foreach ( var data in _keyUpdateActions )
309
+ // Create a copy in case that one of the callbacks modifies the list (Ex: removing a subscriber)
310
+ var copy = new Dictionary < TKey , IList < Action < TKey , TValue , TValue , ObservableUpdateType > > > ( _keyUpdateActions ) ;
311
+
312
+ foreach ( var data in copy )
304
313
{
305
- for ( var i = 0 ; i < data . Value . Count ; i ++ )
314
+ var listCopy = data . Value . ToList ( ) ;
315
+ for ( var i = 0 ; i < listCopy . Count ; i ++ )
306
316
{
307
- data . Value [ i ] ( data . Key , dictionary [ data . Key ] , default , ObservableUpdateType . Removed ) ;
317
+ listCopy [ i ] ( data . Key , Dictionary [ data . Key ] , default , ObservableUpdateType . Removed ) ;
308
318
}
309
319
}
310
320
}
311
321
312
322
if ( ObservableUpdateFlag != ObservableUpdateFlag . KeyUpdateOnly )
313
323
{
314
- foreach ( var data in dictionary )
324
+ foreach ( var data in Dictionary )
315
325
{
316
- for ( var i = 0 ; i < _updateActions . Count ; i ++ )
326
+ var listCopy = _updateActions . ToList ( ) ;
327
+ for ( var i = 0 ; i < listCopy . Count ; i ++ )
317
328
{
318
- _updateActions [ i ] ( data . Key , data . Value , default , ObservableUpdateType . Removed ) ;
329
+ listCopy [ i ] ( data . Key , data . Value , default , ObservableUpdateType . Removed ) ;
319
330
}
320
331
}
321
332
}
333
+
334
+ Dictionary . Clear ( ) ;
322
335
}
323
336
324
337
/// <inheritdoc />
@@ -371,6 +384,7 @@ public void StopObserving(Action<TKey, TValue, TValue, ObservableUpdateType> onU
371
384
if ( actions . Value [ i ] == onUpdate )
372
385
{
373
386
actions . Value . RemoveAt ( i ) ;
387
+ break ;
374
388
}
375
389
}
376
390
}
@@ -380,6 +394,7 @@ public void StopObserving(Action<TKey, TValue, TValue, ObservableUpdateType> onU
380
394
if ( _updateActions [ i ] == onUpdate )
381
395
{
382
396
_updateActions . RemoveAt ( i ) ;
397
+ break ;
383
398
}
384
399
}
385
400
}
@@ -434,6 +449,25 @@ protected void InvokeUpdate(TKey key, TValue previousValue)
434
449
}
435
450
}
436
451
}
452
+
453
+ private int AdjustIndex ( int index , Action < TKey , TValue , TValue , ObservableUpdateType > action ,
454
+ IList < Action < TKey , TValue , TValue , ObservableUpdateType > > list )
455
+ {
456
+ if ( index < list . Count && list [ index ] == action )
457
+ {
458
+ return index ;
459
+ }
460
+
461
+ for ( var i = index - 1 ; i > - 1 ; i -- )
462
+ {
463
+ if ( list [ i ] == action )
464
+ {
465
+ return i ;
466
+ }
467
+ }
468
+
469
+ return index + 1 ;
470
+ }
437
471
}
438
472
439
473
/// <inheritdoc />
0 commit comments