using System.Collections.Concurrent;
using GFramework.Core.Abstractions.Logging;
using GFramework.Core.Abstractions.Resource;
using GFramework.Core.Logging;
namespace GFramework.Core.Resource;
///
/// 资源管理器实现,提供资源加载、缓存和卸载功能
/// 线程安全:所有公共方法都是线程安全的
///
public class ResourceManager : IResourceManager
{
///
/// Path 参数验证错误消息常量
///
private const string PathCannotBeNullOrEmptyMessage = "Path cannot be null or whitespace.";
private readonly ResourceCache _cache = new();
private readonly ConcurrentDictionary _loaders = new();
private readonly object _loadLock = new();
private readonly ILogger _logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(ResourceManager));
private IResourceReleaseStrategy _releaseStrategy;
///
/// 创建资源管理器
/// 默认使用手动释放策略
///
public ResourceManager()
{
_releaseStrategy = new ManualReleaseStrategy();
}
///
/// 获取已加载资源的数量
///
public int LoadedResourceCount => _cache.Count;
///
/// 同步加载资源
///
public T? Load(string path) where T : class
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException(PathCannotBeNullOrEmptyMessage, nameof(path));
// 检查缓存
var cached = _cache.Get(path);
if (cached != null)
{
return cached;
}
// 加载资源
lock (_loadLock)
{
// 双重检查
cached = _cache.Get(path);
if (cached != null)
{
return cached;
}
var loader = GetLoader();
if (loader == null)
{
throw new InvalidOperationException($"No loader registered for type {typeof(T).Name}");
}
try
{
var resource = loader.Load(path);
_cache.Add(path, resource);
return resource;
}
catch (Exception ex)
{
_logger.Error($"Failed to load resource '{path}'", ex);
return null;
}
}
}
///
/// 异步加载资源
///
public async Task LoadAsync(string path) where T : class
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException(PathCannotBeNullOrEmptyMessage, nameof(path));
// 检查缓存
var cached = _cache.Get(path);
if (cached != null)
{
return cached;
}
var loader = GetLoader();
if (loader == null)
{
throw new InvalidOperationException($"No loader registered for type {typeof(T).Name}");
}
try
{
var resource = await loader.LoadAsync(path);
lock (_loadLock)
{
// 双重检查
cached = _cache.Get(path);
if (cached != null)
{
// 已经被其他线程加载了,卸载当前加载的资源
loader.Unload(resource);
return cached;
}
_cache.Add(path, resource);
}
return resource;
}
catch (Exception ex)
{
_logger.Error($"Failed to load resource '{path}'", ex);
return null;
}
}
///
/// 获取资源句柄
///
public IResourceHandle? GetHandle(string path) where T : class
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException(PathCannotBeNullOrEmptyMessage, nameof(path));
var resource = _cache.Get(path);
if (resource == null)
return null;
_cache.AddReference(path);
return new ResourceHandle(resource, path, HandleDispose);
}
///
/// 卸载指定路径的资源
///
public bool Unload(string path)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException(PathCannotBeNullOrEmptyMessage, nameof(path));
lock (_loadLock)
{
var resource = _cache.Get