namespace GFramework.Core.Godot.system;
///
/// 资源工厂类,用于注册和解析各种资源的创建工厂
///
public static class ResourceFactory
{
///
/// 可预加载条目接口,定义了是否需要预加载以及执行工厂的方法
///
private interface IPreloadableEntry
{
///
/// 获取一个值,表示该资源是否需要预加载
///
bool Preload { get; }
///
/// 执行与该条目关联的工厂方法
///
void ExecuteFactory();
}
///
/// 表示一个具体的资源工厂条目,实现 IPreloadableEntry 接口
///
/// 资源类型
private sealed class Entry(Func factory, bool preload) : IPreloadableEntry
{
///
/// 获取用于创建资源的工厂函数
///
public Func Factory { get; } = factory;
///
/// 获取一个值,表示该资源是否需要预加载
///
public bool Preload { get; } = preload;
///
/// 执行工厂函数以创建资源实例
///
public void ExecuteFactory() => Factory();
}
///
/// 工厂注册表,管理所有已注册的资源工厂
///
internal sealed class Registry
{
///
/// 存储所有已注册的工厂函数,键为资源类型,值为对应的工厂条目对象
///
private readonly Dictionary _factories = new();
///
/// 注册指定类型的资源工厂
///
/// 要注册的资源类型
/// 创建该类型资源的工厂函数
/// 是否需要预加载该资源,默认为false
public void Register(Func factory, bool preload = false)
{
_factories[typeof(T)] = new Entry(factory, preload);
}
///
/// 解析并获取指定类型的工厂函数
///
/// 要获取工厂函数的资源类型
/// 指定类型的工厂函数
/// 当指定类型的工厂未注册时抛出异常
public Func Resolve()
{
// 尝试从字典中查找对应类型的工厂条目
if (_factories.TryGetValue(typeof(T), out var obj)
&& obj is Entry entry)
return entry.Factory;
// 若未找到则抛出异常
throw new InvalidOperationException($"Factory not registered: {typeof(T).Name}");
}
///
/// 预加载所有标记为需要预加载的资源
///
public void PreloadAll()
{
// 遍历所有已注册的工厂
foreach (var entry in _factories.Values)
{
// 检查当前条目是否支持预加载且被标记为需预加载
if (entry is IPreloadableEntry preloadable && preloadable.Preload)
{
// 执行其工厂方法进行预加载
preloadable.ExecuteFactory();
}
}
}
}
}