Skip to content

Commit 5a5cf2a

Browse files
committed
Test and prod enhancements
1 parent 44bd38c commit 5a5cf2a

14 files changed

+748
-1025
lines changed

CHANGELOG.md

Lines changed: 5 additions & 132 deletions
Large diffs are not rendered by default.

Editor/Sprites/AnimationCreatorWindow.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,15 @@ private void DrawPreviewPanel(AnimationData data, int animationIndex)
859859
GUILayout.Width(80)
860860
);
861861

862+
// Pre-load all assets to avoid display flickers
863+
if (wantsPreview)
864+
{
865+
foreach (Sprite spriteFrame in data.frames)
866+
{
867+
_ = GetPreviewTexture(spriteFrame);
868+
}
869+
}
870+
862871
if (wantsPreview != data.showPreview)
863872
{
864873
data.showPreview = wantsPreview;

Runtime/Core/DataStructure/Cache.cs

Lines changed: 122 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,13 @@ private struct CacheEntry
7272
// which can cause deadlocks during Unity's "Open Project: Open Scene" phase.
7373
private IRandom _random;
7474
private IRandom Random => _random ??= PRNG.Instance;
75+
private ReaderWriterLockSlim _lock;
7576

7677
#if SINGLE_THREADED
7778
private readonly Dictionary<TKey, int> _keyToIndex;
7879
#else
7980
private readonly ConcurrentDictionary<TKey, int> _keyToIndex;
80-
private readonly object _evictionLock = new object();
8181
#endif
82-
8382
private CacheEntry[] _entries;
8483
private int _count;
8584
private int _capacity;
@@ -246,6 +245,7 @@ public Cache(CacheOptions<TKey, TValue> options)
246245
);
247246
#endif
248247

248+
_lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
249249
_entries = new CacheEntry[initialCapacity];
250250

251251
InitializeFreeList();
@@ -295,16 +295,35 @@ private void InitializeLinkedLists()
295295
/// <returns>True if the key was found and not expired, false otherwise.</returns>
296296
public bool TryGet(TKey key, out TValue value)
297297
{
298-
value = default;
298+
if (_disposed)
299+
{
300+
value = default;
301+
return false;
302+
}
303+
304+
_lock.EnterReadLock();
305+
try
306+
{
307+
return TryGetUnlocked(key, out value);
308+
}
309+
finally
310+
{
311+
_lock.ExitReadLock();
312+
}
313+
}
299314

315+
private bool TryGetUnlocked(TKey key, out TValue value)
316+
{
300317
if (key == null || _disposed)
301318
{
319+
value = default;
302320
return false;
303321
}
304322

305323
if (!_keyToIndex.TryGetValue(key, out int index))
306324
{
307325
RecordMiss();
326+
value = default;
308327
return false;
309328
}
310329

@@ -315,6 +334,7 @@ public bool TryGet(TKey key, out TValue value)
315334
EvictEntry(index, EvictionReason.Expired);
316335
RecordMiss();
317336
RecordExpired();
337+
value = default;
318338
return false;
319339
}
320340

@@ -339,30 +359,51 @@ public TValue GetOrAdd(TKey key, Func<TKey, TValue> factory)
339359
return default;
340360
}
341361

342-
if (TryGet(key, out TValue value))
362+
_lock.EnterUpgradeableReadLock();
363+
try
343364
{
344-
return value;
345-
}
365+
if (TryGetUnlocked(key, out TValue value))
366+
{
367+
return value;
368+
}
346369

347-
Func<TKey, TValue> actualFactory = factory ?? _options.Loader;
348-
if (actualFactory == null)
349-
{
350-
return default;
351-
}
370+
_lock.EnterWriteLock();
371+
try
372+
{
373+
if (TryGetUnlocked(key, out value))
374+
{
375+
return value;
376+
}
352377

353-
TValue newValue;
354-
try
355-
{
356-
newValue = actualFactory(key);
357-
RecordLoad();
378+
Func<TKey, TValue> actualFactory = factory ?? _options.Loader;
379+
if (actualFactory == null)
380+
{
381+
return default;
382+
}
383+
384+
TValue newValue;
385+
try
386+
{
387+
newValue = actualFactory(key);
388+
RecordLoad();
389+
}
390+
catch
391+
{
392+
return default;
393+
}
394+
395+
SetUnlocked(key, newValue);
396+
return newValue;
397+
}
398+
finally
399+
{
400+
_lock.ExitWriteLock();
401+
}
358402
}
359-
catch
403+
finally
360404
{
361-
return default;
405+
_lock.ExitUpgradeableReadLock();
362406
}
363-
364-
Set(key, newValue);
365-
return newValue;
366407
}
367408

368409
/// <summary>
@@ -388,15 +429,18 @@ public void Set(TKey key, TValue value, float? ttlSeconds)
388429
return;
389430
}
390431

391-
#if !SINGLE_THREADED
392-
lock (_evictionLock)
393-
#endif
432+
_lock.EnterWriteLock();
433+
try
434+
{
435+
SetUnlocked(key, value, ttlSeconds);
436+
}
437+
finally
394438
{
395-
SetInternal(key, value, ttlSeconds);
439+
_lock.ExitWriteLock();
396440
}
397441
}
398442

399-
private void SetInternal(TKey key, TValue value, float? ttlSeconds)
443+
private void SetUnlocked(TKey key, TValue value, float? ttlSeconds = null)
400444
{
401445
float currentTime = _timeProvider();
402446

@@ -442,6 +486,7 @@ private void SetInternal(TKey key, TValue value, float? ttlSeconds)
442486
Grow();
443487
break;
444488
}
489+
445490
EvictOne(EvictionReason.Capacity);
446491
}
447492

@@ -508,26 +553,29 @@ public bool TryRemove(TKey key)
508553
/// <returns>True if the entry was removed, false if not found.</returns>
509554
public bool TryRemove(TKey key, out TValue value)
510555
{
511-
value = default;
512-
513556
if (key == null || _disposed)
514557
{
558+
value = default;
515559
return false;
516560
}
517561

518-
#if !SINGLE_THREADED
519-
lock (_evictionLock)
520-
#endif
562+
_lock.EnterWriteLock();
563+
try
521564
{
522565
if (!_keyToIndex.TryGetValue(key, out int index))
523566
{
567+
value = default;
524568
return false;
525569
}
526570

527571
value = _entries[index].Value;
528572
EvictEntry(index, EvictionReason.Explicit);
529573
return true;
530574
}
575+
finally
576+
{
577+
_lock.ExitWriteLock();
578+
}
531579
}
532580

533581
/// <summary>
@@ -540,9 +588,8 @@ public void Clear()
540588
return;
541589
}
542590

543-
#if !SINGLE_THREADED
544-
lock (_evictionLock)
545-
#endif
591+
_lock.EnterWriteLock();
592+
try
546593
{
547594
for (int i = 0; i < _entries.Length; i++)
548595
{
@@ -566,6 +613,10 @@ public void Clear()
566613
InitializeFreeList();
567614
InitializeLinkedLists();
568615
}
616+
finally
617+
{
618+
_lock.ExitWriteLock();
619+
}
569620
}
570621

571622
/// <summary>
@@ -580,17 +631,25 @@ public bool ContainsKey(TKey key)
580631
return false;
581632
}
582633

583-
if (!_keyToIndex.TryGetValue(key, out int index))
634+
_lock.EnterReadLock();
635+
try
584636
{
585-
return false;
586-
}
637+
if (!_keyToIndex.TryGetValue(key, out int index))
638+
{
639+
return false;
640+
}
587641

588-
if (!_entries[index].IsAlive || IsExpired(index, _timeProvider()))
642+
if (!_entries[index].IsAlive || IsExpired(index, _timeProvider()))
643+
{
644+
return false;
645+
}
646+
647+
return true;
648+
}
649+
finally
589650
{
590-
return false;
651+
_lock.ExitReadLock();
591652
}
592-
593-
return true;
594653
}
595654

596655
/// <summary>
@@ -705,9 +764,8 @@ public void CleanUp()
705764
return;
706765
}
707766

708-
#if !SINGLE_THREADED
709-
lock (_evictionLock)
710-
#endif
767+
_lock.EnterWriteLock();
768+
try
711769
{
712770
float currentTime = _timeProvider();
713771
for (int i = 0; i < _entries.Length; i++)
@@ -719,6 +777,10 @@ public void CleanUp()
719777
}
720778
}
721779
}
780+
finally
781+
{
782+
_lock.ExitWriteLock();
783+
}
722784
}
723785

724786
/// <summary>
@@ -737,16 +799,19 @@ public void Compact(float percentage)
737799
percentage = 1f;
738800
}
739801

740-
#if !SINGLE_THREADED
741-
lock (_evictionLock)
742-
#endif
802+
_lock.EnterWriteLock();
803+
try
743804
{
744805
int toEvict = (int)(_count * percentage);
745806
for (int i = 0; i < toEvict && _count > 0; i++)
746807
{
747808
EvictOne(EvictionReason.Capacity);
748809
}
749810
}
811+
finally
812+
{
813+
_lock.ExitWriteLock();
814+
}
750815
}
751816

752817
/// <summary>
@@ -760,17 +825,21 @@ public void Resize(int newCapacity)
760825
return;
761826
}
762827

763-
#if !SINGLE_THREADED
764-
lock (_evictionLock)
765-
#endif
828+
_lock.EnterWriteLock();
829+
try
766830
{
767831
while (_count > newCapacity)
768832
{
769833
EvictOne(EvictionReason.Capacity);
770834
}
835+
771836
_capacity = newCapacity;
772837
_protectedCapacity = (int)(_capacity * _options.ProtectedRatio);
773838
}
839+
finally
840+
{
841+
_lock.ExitWriteLock();
842+
}
774843
}
775844

776845
/// <inheritdoc />
@@ -781,8 +850,10 @@ public void Dispose()
781850
return;
782851
}
783852

784-
_disposed = true;
785853
Clear();
854+
_disposed = true;
855+
_lock.Dispose();
856+
_lock = null;
786857
}
787858

788859
private float ComputeExpirationTime(

0 commit comments

Comments
 (0)