using System; namespace FlowScope.Resources { internal sealed class ResourceEntry { private readonly Action _release; private int _referenceCount; private bool _released; public ResourceEntry(string key, object asset, Action release) : this(key, asset?.GetType(), asset, (_, _, releasedAsset) => release(key, releasedAsset)) { } public ResourceEntry(string key, Type assetType, object asset, Action release) { Key = string.IsNullOrWhiteSpace(key) ? throw new ArgumentException("Resource key is required.", nameof(key)) : key; AssetType = assetType ?? throw new ArgumentNullException(nameof(assetType)); Asset = asset ?? throw new ArgumentNullException(nameof(asset)); _release = release ?? throw new ArgumentNullException(nameof(release)); } public string Key { get; } public Type AssetType { get; } public object Asset { get; private set; } public int ReferenceCount => _referenceCount; public ResourceHandle CreateHandle() where T : class { if (_released) { throw new ObjectDisposedException(nameof(ResourceEntry)); } _referenceCount++; return new ResourceHandle(this); } public void ReleaseHandle() { if (_released) { return; } _referenceCount--; if (_referenceCount > 0) { return; } _released = true; var asset = Asset; Asset = null; _release(Key, AssetType, asset); } public void ReleaseWithoutHandle() { if (_released) { return; } _released = true; var asset = Asset; Asset = null; _release(Key, AssetType, asset); } } }