using GFramework.Core.Abstractions.Logging;
using GFramework.Core.Abstractions.Resource;
using GFramework.Core.Logging;
namespace GFramework.Core.Resource;
///
/// 资源句柄实现,管理资源的生命周期和引用计数
/// 线程安全:所有公共方法都是线程安全的
///
/// 资源类型
internal sealed class ResourceHandle : IResourceHandle where T : class
{
private readonly object _lock = new();
private readonly ILogger _logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(ResourceHandle));
private readonly Action _onDispose;
private bool _disposed;
private int _referenceCount;
///
/// 创建资源句柄
///
/// 资源实例
/// 资源路径
/// 释放时的回调
public ResourceHandle(T resource, string path, Action onDispose)
{
Resource = resource ?? throw new ArgumentNullException(nameof(resource));
Path = path ?? throw new ArgumentNullException(nameof(path));
_onDispose = onDispose ?? throw new ArgumentNullException(nameof(onDispose));
_referenceCount = 1;
}
///
/// 获取资源实例
///
public T? Resource { get; private set; }
///
/// 获取资源路径
///
public string Path { get; }
///
/// 获取资源是否有效
///
public bool IsValid
{
get
{
lock (_lock)
{
return !_disposed && Resource != null;
}
}
}
///
/// 获取当前引用计数
///
public int ReferenceCount
{
get
{
lock (_lock)
{
return _referenceCount;
}
}
}
///
/// 增加引用计数
///
public void AddReference()
{
lock (_lock)
{
if (_disposed)
throw new ObjectDisposedException(nameof(ResourceHandle));
_referenceCount++;
}
}
///
/// 减少引用计数
///
public void RemoveReference()
{
lock (_lock)
{
if (_disposed)
return;
_referenceCount--;
if (_referenceCount <= 0)
{
DisposeInternal();
}
}
}
///
/// 释放资源句柄
///
public void Dispose()
{
lock (_lock)
{
if (_disposed)
return;
_referenceCount--;
if (_referenceCount <= 0)
{
DisposeInternal();
}
}
}
///
/// 内部释放方法(必须在锁内调用)
///
private void DisposeInternal()
{
if (_disposed)
return;
_disposed = true;
Resource = null;
try
{
_onDispose(Path);
}
catch (Exception ex)
{
_logger.Error($"[ResourceHandle] Error disposing resource '{Path}': {ex.Message}");
}
}
}