GwWuYou 7299126a18 refactor(assets): 将资源相关抽象移至专用模块
- 将 AssetCatalog.cs、IAssetCatalogSystem.cs、IResourceFactorySystem.cs 和
  ResourceFactory.cs 从 GFramework.Game 移至 GFramework.Game.Abstractions
- 在 GFramework.Game 项目中添加对 GFramework.Game.Abstractions 的引用
- 更新 AbstractAssetCatalogSystem.cs 以使用新的命名空间引用
- 在 GFramework.Godot 项目中添加对 GFramework.Game.Abstractions 的引用
- 更新 ResourceLoadSystem.cs 以使用新的命名空间并修正命名空间声明
- 在解决方案文件中注册新的 GFramework.Game.Abstractions 项目
- 为 GFramework.Game.Abstractions 项目添加 Directory.Build.props 配置文件
- 在主项目文件中排除新抽象模块的编译和资源文件以避免重复包含
2025-12-28 13:24:29 +08:00

132 lines
4.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
namespace GFramework.Game.Abstractions.assets;
/// <summary>
/// 资源工厂类,用于注册和解析各种资源的创建工厂
/// </summary>
public static class ResourceFactory
{
/// <summary>
/// 可预加载条目接口,定义了是否需要预加载以及执行工厂的方法
/// </summary>
private interface IPreloadableEntry
{
/// <summary>
/// 获取一个值,表示该资源是否需要预加载
/// </summary>
bool Preload { get; }
/// <summary>
/// 获取资源类型
/// </summary>
Type ResourceType { get; }
/// <summary>
/// 获取资源键值
/// </summary>
string Key { get; }
/// <summary>
/// 执行与该条目关联的工厂方法
/// </summary>
void ExecuteFactory();
}
/// <summary>
/// 表示一个具体的资源工厂条目,实现 IPreloadableEntry 接口
/// </summary>
/// <typeparam name="T">资源类型</typeparam>
private sealed class Entry<T>(string key, Func<T> factory, bool preload) : IPreloadableEntry
{
/// <summary>
/// 获取用于创建资源的工厂函数
/// </summary>
public Func<T> Factory { get; } = factory;
/// <summary>
/// 获取一个值,表示该资源是否需要预加载
/// </summary>
public bool Preload { get; } = preload;
/// <summary>
/// 执行工厂函数以创建资源实例
/// </summary>
public void ExecuteFactory()
{
Factory();
}
/// <summary>
/// 获取资源的类型
/// </summary>
public Type ResourceType => typeof(T);
/// <summary>
/// 获取资源的键值
/// </summary>
public string Key { get; } = key;
}
/// <summary>
/// 工厂注册表,管理所有已注册的资源工厂
/// </summary>
public sealed class Registry
{
/// <summary>
/// 存储所有已注册的工厂函数,键为资源类型,值为对应的工厂条目对象
/// </summary>
private readonly Dictionary<(Type type, string key), IPreloadableEntry> _factories = new();
/// <summary>
/// 注册指定类型的资源工厂
/// </summary>
/// <typeparam name="T">要注册的资源类型</typeparam>
/// <param name="key">键</param>
/// <param name="factory">创建该类型资源的工厂函数</param>
/// <param name="preload">是否需要预加载该资源默认为false</param>
public void Register<T>(string key, Func<T> factory, bool preload = false)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentException("Resource key cannot be null or empty.", nameof(key));
var dictKey = (typeof(T), key);
_factories[dictKey] = new Entry<T>(key, factory, preload);
}
/// <summary>
/// 解析并获取指定类型的工厂函数
/// </summary>
/// <typeparam name="T">要获取工厂函数的资源类型</typeparam>
/// <param name="key">资源键</param>
/// <returns>指定类型的工厂函数</returns>
/// <exception cref="InvalidOperationException">当指定类型的工厂未注册时抛出异常</exception>
public Func<T> ResolveFactory<T>(string key)
{
var dictKey = (typeof(T), key);
if (_factories.TryGetValue(dictKey, out var entry)
&& entry is Entry<T> typed)
return typed.Factory;
throw new InvalidOperationException(
$"Factory not registered: {typeof(T).Name} with key '{key}'");
}
/// <summary>
/// 预加载所有标记为需要预加载的资源
/// </summary>
public void PreloadAll()
{
// 遍历所有已注册的工厂
foreach (var entry in _factories.Values.Where(entry => entry.Preload))
// 执行其工厂方法进行预加载
entry.ExecuteFactory();
}
}
}