diff --git a/GFramework.Core.Godot/system/AbstractResourceFactorySystem.cs b/GFramework.Core.Godot/system/AbstractResourceFactorySystem.cs index 9dcd006..449baa1 100644 --- a/GFramework.Core.Godot/system/AbstractResourceFactorySystem.cs +++ b/GFramework.Core.Godot/system/AbstractResourceFactorySystem.cs @@ -35,19 +35,30 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF _registry.PreloadAll(); }); } - /// /// 注册系统所需的各种资源类型。由子类实现具体注册逻辑。 /// protected abstract void RegisterResources(); + /// - /// 获取指定类型的资源工厂函数。 + /// 根据指定的键获取资源工厂函数。 /// - /// 要获取工厂的资源类型 + /// 资源类型 + /// 资源键 /// 返回创建指定类型资源的工厂函数 - public Func Get() => _registry!.Resolve(); + public Func GetFactory(string key)=>_registry!.ResolveFactory(key); + /// + /// 根据资产目录映射信息获取资源工厂函数。 + /// + /// 资源类型 + /// 资产目录映射信息 + /// 返回创建指定类型资源的工厂函数 + public Func GetFactory(AssetCatalog.AssetCatalogMapping mapping) => _registry!.ResolveFactory(mapping.Key); + + + #region Register Helpers(声明式) /// @@ -65,6 +76,7 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF var id = _assetCatalogSystem!.GetScene(sceneKey); _registry!.Register( + sceneKey, _resourceLoadSystem!.GetOrRegisterSceneFactory(id), preload ); @@ -87,6 +99,7 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF var id = _assetCatalogSystem!.GetResource(resourceKey); _registry!.Register( + resourceKey, _resourceLoadSystem!.GetOrRegisterResourceFactory(id, duplicate), preload ); diff --git a/GFramework.Core.Godot/system/IResourceFactorySystem.cs b/GFramework.Core.Godot/system/IResourceFactorySystem.cs index eb84e49..4fec531 100644 --- a/GFramework.Core.Godot/system/IResourceFactorySystem.cs +++ b/GFramework.Core.Godot/system/IResourceFactorySystem.cs @@ -8,9 +8,19 @@ namespace GFramework.Core.Godot.system; public interface IResourceFactorySystem : ISystem { /// - /// 获取指定类型T的资源创建函数 + /// 根据指定键名获取指定类型T的资源创建函数 /// /// 要获取创建函数的资源类型 + /// 用于标识资源的键名 /// 返回一个创建T类型实例的函数委托 - Func Get(); + Func GetFactory(string key); + + /// + /// 根据资产目录映射获取指定类型T的资源创建函数 + /// + /// 要获取创建函数的资源类型 + /// 资产目录映射信息 + /// 返回一个创建T类型实例的函数委托 + Func GetFactory(AssetCatalog.AssetCatalogMapping mapping); } + diff --git a/GFramework.Core.Godot/system/ResourceFactory.cs b/GFramework.Core.Godot/system/ResourceFactory.cs index fd680fb..dfb2de6 100644 --- a/GFramework.Core.Godot/system/ResourceFactory.cs +++ b/GFramework.Core.Godot/system/ResourceFactory.cs @@ -19,13 +19,24 @@ public static class ResourceFactory /// 执行与该条目关联的工厂方法 /// void ExecuteFactory(); + + /// + /// 获取资源类型 + /// + Type ResourceType { get; } + + /// + /// 获取资源键值 + /// + string Key { get; } } + /// /// 表示一个具体的资源工厂条目,实现 IPreloadableEntry 接口 /// /// 资源类型 - private sealed class Entry(Func factory, bool preload) : IPreloadableEntry + private sealed class Entry(string key, Func factory, bool preload) : IPreloadableEntry { /// /// 获取用于创建资源的工厂函数 @@ -41,8 +52,19 @@ public static class ResourceFactory /// 执行工厂函数以创建资源实例 /// public void ExecuteFactory() => Factory(); + + /// + /// 获取资源的类型 + /// + public Type ResourceType => typeof(T); + + /// + /// 获取资源的键值 + /// + public string Key { get; } = key; } + /// /// 工厂注册表,管理所有已注册的资源工厂 /// @@ -51,50 +73,56 @@ public static class ResourceFactory /// /// 存储所有已注册的工厂函数,键为资源类型,值为对应的工厂条目对象 /// - private readonly Dictionary _factories = new(); + private readonly Dictionary<(Type type, string key), IPreloadableEntry> _factories = new(); /// /// 注册指定类型的资源工厂 /// /// 要注册的资源类型 + /// 键 /// 创建该类型资源的工厂函数 /// 是否需要预加载该资源,默认为false - public void Register(Func factory, bool preload = false) + public void Register(string key, Func factory, bool preload = false) { - _factories[typeof(T)] = new Entry(factory, preload); + 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(key, factory, preload); } /// /// 解析并获取指定类型的工厂函数 /// /// 要获取工厂函数的资源类型 + /// 资源键 /// 指定类型的工厂函数 /// 当指定类型的工厂未注册时抛出异常 - public Func Resolve() + public Func ResolveFactory(string key) { - // 尝试从字典中查找对应类型的工厂条目 - if (_factories.TryGetValue(typeof(T), out var obj) - && obj is Entry entry) - return entry.Factory; + var dictKey = (typeof(T), key); - // 若未找到则抛出异常 - throw new InvalidOperationException($"Factory not registered: {typeof(T).Name}"); + if (_factories.TryGetValue(dictKey, out var entry) + && entry is Entry typed) + { + return typed.Factory; + } + + throw new InvalidOperationException( + $"Factory not registered: {typeof(T).Name} with key '{key}'"); } - + /// /// 预加载所有标记为需要预加载的资源 /// public void PreloadAll() { // 遍历所有已注册的工厂 - foreach (var entry in _factories.Values) + foreach (var entry in _factories.Values.Where(entry => entry.Preload)) { - // 检查当前条目是否支持预加载且被标记为需预加载 - if (entry is IPreloadableEntry preloadable && preloadable.Preload) - { - // 执行其工厂方法进行预加载 - preloadable.ExecuteFactory(); - } + // 执行其工厂方法进行预加载 + entry.ExecuteFactory(); } } }