From 87042fb8223a9d8dac9ca4fc80a19a5c128cd916 Mon Sep 17 00:00:00 2001
From: GwWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Thu, 18 Dec 2025 21:19:14 +0800
Subject: [PATCH] =?UTF-8?q?feat(core):=20=E9=87=8D=E6=9E=84=E8=B5=84?=
=?UTF-8?q?=E6=BA=90=E5=B7=A5=E5=8E=82=E7=B3=BB=E7=BB=9F=E4=BB=A5=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E9=94=AE=E6=8E=A7=E8=B5=84=E6=BA=90=E6=B3=A8=E5=86=8C?=
=?UTF-8?q?=E4=B8=8E=E8=A7=A3=E6=9E=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 引入基于键的资源工厂注册机制,替换原有的类型唯一注册方式
- 更新资源工厂接口,新增 GetFactory 方法支持键名参数
- 修改内部注册表结构,使用 (Type, string) 元组作为工厂字典键
- 在注册场景和资源时传入键名,确保资源可按名称区分
- 增强资源工厂条目信息,添加 ResourceType 和 Key 属性
- 完善工厂解析逻辑,通过类型和键双重条件匹配目标工厂
- 添加对空键值的校验,防止无效键导致运行时错误
- 优化预加载流程,仅执行明确标记为预加载的资源工厂
---
.../system/AbstractResourceFactorySystem.cs | 21 ++++--
.../system/IResourceFactorySystem.cs | 14 +++-
.../system/ResourceFactory.cs | 66 +++++++++++++------
3 files changed, 76 insertions(+), 25 deletions(-)
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();
}
}
}