using System; using System.Collections.Concurrent; using System.Collections.Generic; using LightlessSync.API.Data; using LightlessSync.Utils; namespace LightlessSync.PlayerData.Pairs; /// /// cache for character/pair data and penumbra collections /// public sealed class PairStateCache { private readonly ConcurrentDictionary _cache = new(StringComparer.Ordinal); public void Store(string ident, CharacterData data) { if (string.IsNullOrEmpty(ident) || data is null) { return; } var state = _cache.GetOrAdd(ident, _ => new PairState()); state.CharacterData = data.DeepClone(); } public CharacterData? TryLoad(string ident) { if (string.IsNullOrEmpty(ident)) { return null; } if (_cache.TryGetValue(ident, out var state) && state.CharacterData is not null) { return state.CharacterData.DeepClone(); } return null; } public Guid? TryGetTemporaryCollection(string ident) { if (string.IsNullOrEmpty(ident)) { return null; } if (_cache.TryGetValue(ident, out var state)) { return state.TemporaryCollectionId; } return null; } public Guid? StoreTemporaryCollection(string ident, Guid collection) { if (string.IsNullOrEmpty(ident) || collection == Guid.Empty) { return null; } var state = _cache.GetOrAdd(ident, _ => new PairState()); state.TemporaryCollectionId = collection; return collection; } public Guid? ClearTemporaryCollection(string ident) { if (string.IsNullOrEmpty(ident)) { return null; } if (_cache.TryGetValue(ident, out var state)) { var existing = state.TemporaryCollectionId; state.TemporaryCollectionId = null; TryRemoveIfEmpty(ident, state); return existing; } return null; } public IReadOnlyList ClearAllTemporaryCollections() { var removed = new List(); foreach (var (ident, state) in _cache) { if (state.TemporaryCollectionId is { } guid && guid != Guid.Empty) { removed.Add(guid); state.TemporaryCollectionId = null; } TryRemoveIfEmpty(ident, state); } return removed; } public void Clear(string ident) { if (string.IsNullOrEmpty(ident)) { return; } _cache.TryRemove(ident, out _); } private void TryRemoveIfEmpty(string ident, PairState state) { if (state.IsEmpty) { _cache.TryRemove(ident, out _); } } }