From 2db09e72d7097bc4fa8e49daf623a57bfd4cfcbd Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Sat, 20 Dec 2025 13:45:49 +0800 Subject: [PATCH] =?UTF-8?q?refactor(assets):=20=E9=87=8D=E6=9E=84=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E7=9B=AE=E5=BD=95=E7=B3=BB=E7=BB=9F=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9A=E7=A7=8D=E8=B5=84=E6=BA=90=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 AbstractAssetCatalogSystem 从 GFramework.Godot 移动到 GFramework.Game - 引入 GameUnitId、TemplateId 和 AssetId 替代原有的 SceneId 和 ResourceId - 更新注册与查询接口以区分不同类型资源 - 修改相关系统类以适配新的资产标识符类型 - 调整项目引用依赖关系,确保正确的程序集链接 - 扩展资源工厂系统以处理新增的资源类别 - [no tag] --- GFramework.Game/GFramework.Game.csproj | 4 +- .../assets/AbstractAssetCatalogSystem.cs | 166 ++++++++++++++++++ .../assets}/AssetCatalog.cs | 24 ++- GFramework.Game/assets/IAssetCatalogSystem.cs | 91 ++++++++++ .../assets}/IResourceFactorySystem.cs | 2 +- .../assets}/ResourceFactory.cs | 4 +- GFramework.Godot/GFramework.Godot.csproj | 1 - .../system/AbstractAssetCatalogSystem.cs | 117 ------------ .../system/AbstractAudioManagerSystem.cs | 5 +- .../system/AbstractInputSystem.cs | 2 + .../system/AbstractResourceFactorySystem.cs | 70 +++++--- .../system/IAssetCatalogSystem.cs | 37 ---- .../system/IResourceLoadSystem.cs | 37 ++-- GFramework.Godot/system/ResourceLoadSystem.cs | 52 +++--- 14 files changed, 374 insertions(+), 238 deletions(-) create mode 100644 GFramework.Game/assets/AbstractAssetCatalogSystem.cs rename {GFramework.Godot/system => GFramework.Game/assets}/AssetCatalog.cs (55%) create mode 100644 GFramework.Game/assets/IAssetCatalogSystem.cs rename {GFramework.Godot/system => GFramework.Game/assets}/IResourceFactorySystem.cs (96%) rename {GFramework.Godot/system => GFramework.Game/assets}/ResourceFactory.cs (98%) delete mode 100644 GFramework.Godot/system/AbstractAssetCatalogSystem.cs delete mode 100644 GFramework.Godot/system/IAssetCatalogSystem.cs diff --git a/GFramework.Game/GFramework.Game.csproj b/GFramework.Game/GFramework.Game.csproj index 6bbf9c1..6faca1d 100644 --- a/GFramework.Game/GFramework.Game.csproj +++ b/GFramework.Game/GFramework.Game.csproj @@ -10,5 +10,7 @@ - + + + diff --git a/GFramework.Game/assets/AbstractAssetCatalogSystem.cs b/GFramework.Game/assets/AbstractAssetCatalogSystem.cs new file mode 100644 index 0000000..bb956a2 --- /dev/null +++ b/GFramework.Game/assets/AbstractAssetCatalogSystem.cs @@ -0,0 +1,166 @@ +using GFramework.Core.system; + +namespace GFramework.Game.assets; + +/// +/// 资源目录系统抽象基类,用于管理和注册游戏中的场景和资源。 +/// 提供了统一的接口来注册和查询不同类型的资产(如游戏单元、模板、普通资源)。 +/// 子类需要实现 方法以完成具体资产的注册逻辑。 +/// +public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalogSystem +{ + private readonly Dictionary _gameUnits = new(); + private readonly Dictionary _templates = new(); + private readonly Dictionary _assets = new(); + + + /// + /// 系统初始化时调用,用于触发资产注册流程。 + /// 此方法会调用抽象方法 ,由子类提供实际注册逻辑。 + /// + protected override void OnInit() + { + RegisterAssets(); + } + + /// + /// 抽象方法,必须在子类中重写。用于定义具体的资产注册逻辑。 + /// 在此方法中应通过调用各种 Register 方法将资产信息添加到系统中。 + /// + protected abstract void RegisterAssets(); + + #region Register(内部 or Module 使用) + + /// + /// 注册一个游戏单元(GameUnit),使用指定的键和路径。 + /// + /// 唯一标识该游戏单元的字符串键。 + /// 该游戏单元对应的资源路径。 + /// 当键已存在时抛出异常。 + public void RegisterGameUnit(string key, string path) + { + if (!_gameUnits.TryAdd(key, new AssetCatalog.GameUnitId(path))) + throw new InvalidOperationException($"GameUnit key duplicated: {key}"); + } + + /// + /// 根据映射对象注册一个游戏单元(GameUnit)。 + /// + /// 包含键与ID映射关系的对象。 + /// + /// 当映射ID不是 类型或键重复时抛出异常。 + /// + public void RegisterGameUnit(AssetCatalog.AssetCatalogMapping mapping) + { + if (mapping.Id is not AssetCatalog.GameUnitId sceneId) + throw new InvalidOperationException("Mapping ID is not a GameUnitId"); + + if (!_gameUnits.TryAdd(mapping.Key, sceneId)) + throw new InvalidOperationException($"Scene key duplicated: {mapping.Key}"); + } + + /// + /// 注册一个模板资源(Template),使用指定的键和路径。 + /// + /// 唯一标识该模板的字符串键。 + /// 该模板对应的资源路径。 + /// 当键已存在时抛出异常。 + public void RegisterTemplate(string key, string path) + { + if (!_templates.TryAdd(key, new AssetCatalog.TemplateId(path))) + throw new InvalidOperationException($"Template key duplicated: {key}"); + } + + /// + /// 根据映射对象注册一个模板资源(Template)。 + /// + /// 包含键与ID映射关系的对象。 + /// + /// 当映射ID不是 类型或键重复时抛出异常。 + /// + public void RegisterTemplate(AssetCatalog.AssetCatalogMapping mapping) + { + if (mapping.Id is not AssetCatalog.TemplateId templateId) + throw new InvalidOperationException("Mapping ID is not a TemplateId"); + + if (!_templates.TryAdd(mapping.Key, templateId)) + throw new InvalidOperationException($"Template key duplicated: {mapping.Key}"); + } + + /// + /// 注册一个通用资源(Asset),使用指定的键和路径。 + /// + /// 唯一标识该资源的字符串键。 + /// 该资源对应的资源路径。 + /// 当键已存在时抛出异常。 + public void RegisterAsset(string key, string path) + { + if (!_assets.TryAdd(key, new AssetCatalog.AssetId(path))) + throw new InvalidOperationException($"Asset key duplicated: {key}"); + } + + /// + /// 根据映射对象注册一个通用资源(Asset)。 + /// + /// 包含键与ID映射关系的对象。 + /// + /// 当映射ID不是 类型或键重复时抛出异常。 + /// + public void RegisterAsset(AssetCatalog.AssetCatalogMapping mapping) + { + if (mapping.Id is not AssetCatalog.AssetId assetId) + throw new InvalidOperationException("Mapping ID is not a AssetId"); + + if (!_assets.TryAdd(mapping.Key, assetId)) + throw new InvalidOperationException($"Asset key duplicated: {mapping.Key}"); + } + #endregion + + #region Query(对外) + + /// + /// 获取指定键对应的游戏单元ID。 + /// + /// 要查找的游戏单元键。 + /// 对应的游戏单元ID。 + /// 如果未找到指定键则抛出异常。 + public AssetCatalog.GameUnitId GetGameUnit(string key) => _gameUnits[key]; + + /// + /// 获取指定键对应的模板资源ID。 + /// + /// 要查找的模板资源键。 + /// 对应的模板资源ID。 + /// 如果未找到指定键则抛出异常。 + public AssetCatalog.TemplateId GetTemplate(string key) => _templates[key]; + + /// + /// 获取指定键对应的通用资源ID。 + /// + /// 要查找的通用资源键。 + /// 对应的通用资源ID。 + /// 如果未找到指定键则抛出异常。 + public AssetCatalog.AssetId GetAsset(string key) => _assets[key]; + + /// + /// 判断是否存在指定键的游戏单元。 + /// + /// 要检查的游戏单元键。 + /// 若存在返回 true,否则返回 false。 + public bool HasGameUnit(string key) => _gameUnits.ContainsKey(key); + + /// + /// 判断是否存在指定键的模板资源。 + /// + /// 要检查的模板资源键。 + /// 若存在返回 true,否则返回 false。 + public bool HasTemplate(string key) => _templates.ContainsKey(key); + + /// + /// 判断是否存在指定键的通用资源。 + /// + /// 要检查的通用资源键。 + /// 若存在返回 true,否则返回 false。 + public bool HasAsset(string key) => _assets.ContainsKey(key); + #endregion +} diff --git a/GFramework.Godot/system/AssetCatalog.cs b/GFramework.Game/assets/AssetCatalog.cs similarity index 55% rename from GFramework.Godot/system/AssetCatalog.cs rename to GFramework.Game/assets/AssetCatalog.cs index 15edf32..67f8c3d 100644 --- a/GFramework.Godot/system/AssetCatalog.cs +++ b/GFramework.Game/assets/AssetCatalog.cs @@ -1,5 +1,5 @@  -namespace GFramework.Godot.system; +namespace GFramework.Game.assets; /// /// 资源目录类,用于定义和管理游戏中的场景和资源标识符 @@ -23,17 +23,23 @@ public static class AssetCatalog /// 资源目录的键 /// 资源标识符 public readonly record struct AssetCatalogMapping(string Key, IAssetId Id); - + /// - /// 场景标识符结构体,用于唯一标识一个场景资源 + /// 模板资源标识符结构体,实现IAssetId接口 /// - /// 场景资源的路径 - public readonly record struct SceneId(string Path) : IAssetId; - + /// 资源路径 + public readonly record struct TemplateId(string Path) : IAssetId; + /// - /// 资源标识符结构体,用于唯一标识一个游戏资源 + /// 游戏单位资源标识符结构体,实现IAssetId接口 /// - /// 游戏资源的路径 - public readonly record struct ResourceId(string Path) : IAssetId; + /// 资源路径 + public readonly record struct GameUnitId(string Path) : IAssetId; + + /// + /// 通用资源标识符结构体,实现IAssetId接口 + /// + /// 资源路径 + public readonly record struct AssetId(string Path) : IAssetId; } diff --git a/GFramework.Game/assets/IAssetCatalogSystem.cs b/GFramework.Game/assets/IAssetCatalogSystem.cs new file mode 100644 index 0000000..4563bf5 --- /dev/null +++ b/GFramework.Game/assets/IAssetCatalogSystem.cs @@ -0,0 +1,91 @@ +using GFramework.Core.system; + +namespace GFramework.Game.assets; + +/// +/// 资源目录系统接口,用于管理场景和资源的获取与查询 +/// +public interface IAssetCatalogSystem : ISystem +{ + /// + /// 根据指定的键获取游戏单位ID + /// + /// 用于查找游戏单位的键值 + /// 返回对应的游戏单位ID,如果未找到则返回默认值 + AssetCatalog.GameUnitId GetGameUnit(string key); + + /// + /// 根据指定的键获取模板ID + /// + /// 用于查找模板的键值 + /// 返回对应的模板ID,如果未找到则返回默认值 + AssetCatalog.TemplateId GetTemplate(string key); + + /// + /// 根据指定的键获取资源ID + /// + /// 用于查找资源的键值 + /// 返回对应的资源ID,如果未找到则返回默认值 + AssetCatalog.AssetId GetAsset(string key); + + /// + /// 注册游戏单位资源到资产目录中 + /// + /// 游戏单位的唯一标识键值 + /// 游戏单位资源的路径 + void RegisterGameUnit(string key, string path); + + /// + /// 根据映射配置注册游戏单位资源到资产目录中 + /// + /// 包含键值和路径映射关系的配置对象 + void RegisterGameUnit(AssetCatalog.AssetCatalogMapping mapping); + + /// + /// 注册模板资源到资产目录中 + /// + /// 模板的唯一标识键值 + /// 模板资源的路径 + void RegisterTemplate(string key, string path); + + /// + /// 根据映射配置注册模板资源到资产目录中 + /// + /// 包含键值和路径映射关系的配置对象 + void RegisterTemplate(AssetCatalog.AssetCatalogMapping mapping); + + /// + /// 注册普通资产资源到资产目录中 + /// + /// 资产的唯一标识键值 + /// 资产资源的路径 + void RegisterAsset(string key, string path); + + /// + /// 根据映射配置注册普通资产资源到资产目录中 + /// + /// 包含键值和路径映射关系的配置对象 + void RegisterAsset(AssetCatalog.AssetCatalogMapping mapping); + + /// + /// 检查是否存在指定键的游戏单位 + /// + /// 用于查找游戏单位的键值 + /// 存在返回true,否则返回false + bool HasGameUnit(string key); + + /// + /// 检查是否存在指定键的模板 + /// + /// 用于查找模板的键值 + /// 存在返回true,否则返回false + bool HasTemplate(string key); + + /// + /// 检查是否存在指定键的资源 + /// + /// 用于查找资源的键值 + /// 存在返回true,否则返回false + bool HasAsset(string key); + +} diff --git a/GFramework.Godot/system/IResourceFactorySystem.cs b/GFramework.Game/assets/IResourceFactorySystem.cs similarity index 96% rename from GFramework.Godot/system/IResourceFactorySystem.cs rename to GFramework.Game/assets/IResourceFactorySystem.cs index 793dbc9..a6a0753 100644 --- a/GFramework.Godot/system/IResourceFactorySystem.cs +++ b/GFramework.Game/assets/IResourceFactorySystem.cs @@ -1,6 +1,6 @@ using GFramework.Core.system; -namespace GFramework.Godot.system; +namespace GFramework.Game.assets; /// /// 资源工厂系统接口,用于获取指定类型的资源创建函数 diff --git a/GFramework.Godot/system/ResourceFactory.cs b/GFramework.Game/assets/ResourceFactory.cs similarity index 98% rename from GFramework.Godot/system/ResourceFactory.cs rename to GFramework.Game/assets/ResourceFactory.cs index 8137b2c..b46e258 100644 --- a/GFramework.Godot/system/ResourceFactory.cs +++ b/GFramework.Game/assets/ResourceFactory.cs @@ -1,4 +1,4 @@ -namespace GFramework.Godot.system; +namespace GFramework.Game.assets; /// /// 资源工厂类,用于注册和解析各种资源的创建工厂 @@ -68,7 +68,7 @@ public static class ResourceFactory /// /// 工厂注册表,管理所有已注册的资源工厂 /// - internal sealed class Registry + public sealed class Registry { /// /// 存储所有已注册的工厂函数,键为资源类型,值为对应的工厂条目对象 diff --git a/GFramework.Godot/GFramework.Godot.csproj b/GFramework.Godot/GFramework.Godot.csproj index 5c76886..fc85a79 100644 --- a/GFramework.Godot/GFramework.Godot.csproj +++ b/GFramework.Godot/GFramework.Godot.csproj @@ -14,7 +14,6 @@ - diff --git a/GFramework.Godot/system/AbstractAssetCatalogSystem.cs b/GFramework.Godot/system/AbstractAssetCatalogSystem.cs deleted file mode 100644 index fb14996..0000000 --- a/GFramework.Godot/system/AbstractAssetCatalogSystem.cs +++ /dev/null @@ -1,117 +0,0 @@ -using GFramework.Core.system; - -namespace GFramework.Godot.system; - -/// -/// 资源目录系统抽象基类,用于管理和注册游戏中的场景和资源 -/// -public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalogSystem -{ - private readonly Dictionary _scenes = new(); - private readonly Dictionary _resources = new(); - - /// - /// 系统初始化时调用,用于注册所有资产 - /// - protected override void OnInit() - { - RegisterAssets(); - } - - /// - /// 抽象方法,由子类实现具体的资产注册逻辑 - /// - protected abstract void RegisterAssets(); - - #region Register(内部 or Module 使用) - - /// - /// 注册场景资源 - /// - /// 场景的唯一标识键 - /// 场景资源的路径 - /// 当场景键已存在时抛出异常 - public void RegisterScene(string key, string path) - { - if (_scenes.ContainsKey(key)) - throw new InvalidOperationException($"Scene key duplicated: {key}"); - - _scenes[key] = new AssetCatalog.SceneId(path); - } - - /// - /// 注册场景资源 - /// - /// 包含键和场景标识符的映射对象 - /// 当场景键已存在时抛出异常 - public void RegisterScene(AssetCatalog.AssetCatalogMapping mapping) - { - if (mapping.Id is not AssetCatalog.SceneId sceneId) - throw new InvalidOperationException("Mapping ID is not a SceneId"); - - if (!_scenes.TryAdd(mapping.Key, sceneId)) - throw new InvalidOperationException($"Scene key duplicated: {mapping.Key}"); - } - - /// - /// 注册普通资源 - /// - /// 资源的唯一标识键 - /// 资源的路径 - /// 当资源键已存在时抛出异常 - public void RegisterResource(string key, string path) - { - if (_resources.ContainsKey(key)) - throw new InvalidOperationException($"Resource key duplicated: {key}"); - - _resources[key] = new AssetCatalog.ResourceId(path); - } - - /// - /// 注册普通资源 - /// - /// 包含键和资源标识符的映射对象 - /// 当资源键已存在时抛出异常 - public void RegisterResource(AssetCatalog.AssetCatalogMapping mapping) - { - if (mapping.Id is not AssetCatalog.ResourceId resourceId) - throw new InvalidOperationException("Mapping ID is not a ResourceId"); - - if (!_resources.TryAdd(mapping.Key, resourceId)) - throw new InvalidOperationException($"Resource key duplicated: {mapping.Key}"); - } - - #endregion - - #region Query(对外) - - /// - /// 根据键获取场景ID - /// - /// 场景的唯一标识键 - /// 对应的场景ID - public AssetCatalog.SceneId GetScene(string key) => _scenes[key]; - - /// - /// 根据键获取资源ID - /// - /// 资源的唯一标识键 - /// 对应的资源ID - public AssetCatalog.ResourceId GetResource(string key) => _resources[key]; - - /// - /// 检查是否存在指定键的场景 - /// - /// 场景的唯一标识键 - /// 如果存在返回true,否则返回false - public bool HasScene(string key) => _scenes.ContainsKey(key); - - /// - /// 检查是否存在指定键的资源 - /// - /// 资源的唯一标识键 - /// 如果存在返回true,否则返回false - public bool HasResource(string key) => _resources.ContainsKey(key); - - #endregion -} diff --git a/GFramework.Godot/system/AbstractAudioManagerSystem.cs b/GFramework.Godot/system/AbstractAudioManagerSystem.cs index 29816e3..6b0de52 100644 --- a/GFramework.Godot/system/AbstractAudioManagerSystem.cs +++ b/GFramework.Godot/system/AbstractAudioManagerSystem.cs @@ -1,5 +1,6 @@ using GFramework.Core.extensions; using GFramework.Core.system; +using GFramework.Game.assets; using Godot; namespace GFramework.Godot.system; @@ -179,7 +180,7 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager /// 音乐资源ID /// 音量大小,范围0-1 /// 是否循环播放 - public virtual void PlayMusic(AssetCatalog.ResourceId musicId, float volume = 1.0f, bool loop = true) + public virtual void PlayMusic(AssetCatalog.AssetId musicId, float volume = 1.0f, bool loop = true) { PlayMusic(musicId.Path, volume, loop); } @@ -266,7 +267,7 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager /// 音效资源ID /// 音量大小,范围0-1 /// 音调调整 - public virtual void PlaySound(AssetCatalog.ResourceId soundId, float volume = 1.0f, float pitch = 1.0f) + public virtual void PlaySound(AssetCatalog.AssetId soundId, float volume = 1.0f, float pitch = 1.0f) { PlaySound(soundId.Path, volume, pitch); } diff --git a/GFramework.Godot/system/AbstractInputSystem.cs b/GFramework.Godot/system/AbstractInputSystem.cs index 37026bd..cd70213 100644 --- a/GFramework.Godot/system/AbstractInputSystem.cs +++ b/GFramework.Godot/system/AbstractInputSystem.cs @@ -1,3 +1,5 @@ +using GFramework.Game.assets; + namespace GFramework.Godot.system; /// diff --git a/GFramework.Godot/system/AbstractResourceFactorySystem.cs b/GFramework.Godot/system/AbstractResourceFactorySystem.cs index 5df0c2a..53a80f4 100644 --- a/GFramework.Godot/system/AbstractResourceFactorySystem.cs +++ b/GFramework.Godot/system/AbstractResourceFactorySystem.cs @@ -1,11 +1,11 @@ using GFramework.Core.events; using GFramework.Core.extensions; using GFramework.Core.system; +using GFramework.Game.assets; using Godot; namespace GFramework.Godot.system; - /// /// 资源工厂系统抽象基类,用于统一管理各类资源的创建与预加载逻辑。 /// 提供注册场景和资源的方法,并通过依赖的资源加载系统和资产目录系统完成实际资源的获取与构造。 @@ -15,7 +15,7 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF private ResourceFactory.Registry? _registry; private IResourceLoadSystem? _resourceLoadSystem; private IAssetCatalogSystem? _assetCatalogSystem; - + /// /// 系统初始化方法,在系统启动时执行一次。 /// 初始化资源注册表,并获取依赖的资源加载系统和资产目录系统。 @@ -35,11 +35,12 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF _registry.PreloadAll(); }); } + /// /// 注册系统所需的各种资源类型。由子类实现具体注册逻辑。 /// protected abstract void RegisterResources(); - + /// /// 根据指定的键获取资源工厂函数。 @@ -47,8 +48,8 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF /// 资源类型 /// 资源键 /// 返回创建指定类型资源的工厂函数 - public Func GetFactory(string key)=>_registry!.ResolveFactory(key); - + public Func GetFactory(string key) => _registry!.ResolveFactory(key); + /// /// 根据资产目录映射信息获取资源工厂函数。 /// @@ -58,52 +59,67 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF public Func GetFactory(AssetCatalog.AssetCatalogMapping mapping) => _registry!.ResolveFactory(mapping.Key); - #region Register Helpers(声明式) /// - /// 注册场景资源工厂。 - /// 根据场景键名获取场景ID,并将场景加载工厂注册到注册表中。 + /// 注册游戏单位资源到资源管理系统中 /// - /// 场景节点类型,必须继承自Node - /// 场景在资产目录中的键名 - /// 是否需要预加载该场景资源 - protected void RegisterScene( + /// 游戏单位类型,必须继承自Node + /// 场景键值,用于标识特定的游戏单位资源 + /// 是否预加载该资源,默认为false + public void RegisterGameUnit( string sceneKey, bool preload = false) where T : Node { - var id = _assetCatalogSystem!.GetScene(sceneKey); + var id = _assetCatalogSystem!.GetGameUnit(sceneKey); _registry!.Register( sceneKey, - _resourceLoadSystem!.GetOrRegisterSceneFactory(id), + _resourceLoadSystem!.GetOrRegisterGameUnitFactory(id), preload ); } /// - /// 注册普通资源工厂。 - /// 根据资源键名获取资源ID,并将资源加载工厂注册到注册表中。 + /// 注册模板资源到资源管理系统中 /// - /// 资源类型,必须继承自Resource - /// 资源在资产目录中的键名 - /// 是否需要复制资源实例 - /// 是否需要预加载该资源 - protected void RegisterResource( - string resourceKey, - bool duplicate = false, + /// 模板类型,必须继承自Node + /// 模板键值,用于标识特定的模板资源 + /// 是否预加载该资源,默认为false + public void RegisterTemplate( + string templateKey, + bool preload = false) + where T : Node + { + var id = _assetCatalogSystem!.GetTemplate(templateKey); + + _registry!.Register( + templateKey, + _resourceLoadSystem!.GetOrRegisterTemplateFactory(id), + preload + ); + } + + /// + /// 注册通用资产资源到资源管理系统中 + /// + /// 资产类型,必须继承自Resource + /// 资产键值,用于标识特定的资产资源 + /// 是否预加载该资源,默认为false + public void RegisterAsset( + string assetKey, bool preload = false) where T : Resource { - var id = _assetCatalogSystem!.GetResource(resourceKey); + var id = _assetCatalogSystem!.GetAsset(assetKey); _registry!.Register( - resourceKey, - _resourceLoadSystem!.GetOrRegisterResourceFactory(id, duplicate), + assetKey, + _resourceLoadSystem!.GetOrRegisterAssetFactory(id), preload ); } #endregion -} +} \ No newline at end of file diff --git a/GFramework.Godot/system/IAssetCatalogSystem.cs b/GFramework.Godot/system/IAssetCatalogSystem.cs deleted file mode 100644 index fe66618..0000000 --- a/GFramework.Godot/system/IAssetCatalogSystem.cs +++ /dev/null @@ -1,37 +0,0 @@ -using GFramework.Core.system; - -namespace GFramework.Godot.system; - -/// -/// 资源目录系统接口,用于管理场景和资源的获取与查询 -/// -public interface IAssetCatalogSystem : ISystem -{ - /// - /// 根据键名获取场景标识符 - /// - /// 场景的唯一键名 - /// 返回对应的场景ID - AssetCatalog.SceneId GetScene(string key); - - /// - /// 根据键名获取资源标识符 - /// - /// 资源的唯一键名 - /// 返回对应的资源ID - AssetCatalog.ResourceId GetResource(string key); - - /// - /// 检查是否存在指定键名的场景 - /// - /// 要检查的场景键名 - /// 如果存在返回true,否则返回false - bool HasScene(string key); - - /// - /// 检查是否存在指定键名的资源 - /// - /// 要检查的资源键名 - /// 如果存在返回true,否则返回false - bool HasResource(string key); -} diff --git a/GFramework.Godot/system/IResourceLoadSystem.cs b/GFramework.Godot/system/IResourceLoadSystem.cs index fa94e89..57b050d 100644 --- a/GFramework.Godot/system/IResourceLoadSystem.cs +++ b/GFramework.Godot/system/IResourceLoadSystem.cs @@ -1,4 +1,5 @@ using GFramework.Core.system; +using GFramework.Game.assets; using Godot; namespace GFramework.Godot.system; @@ -22,6 +23,7 @@ public interface IResourceLoadSystem : ISystem /// 场景路径 /// 场景的延迟加载包装器 public Lazy GetSceneLoader(string path); + /// /// 创建指定路径场景的实例 /// @@ -30,24 +32,37 @@ public interface IResourceLoadSystem : ISystem /// 场景实例化的节点对象 public T? CreateInstance(string path) where T : Node; - /// - /// 获取或注册场景工厂函数 + /// 获取或注册游戏单位工厂函数 /// /// 节点类型,必须继承自Node /// 场景资源标识符 /// 创建场景实例的工厂函数 - public Func GetOrRegisterSceneFactory(AssetCatalog.SceneId id) where T : Node; - + Func GetOrRegisterGameUnitFactory( + AssetCatalog.GameUnitId id + ) where T : Node; + /// - /// 获取或注册资源工厂函数 + /// 获取或注册模板资源工厂函数 /// - /// 资源类型,必须继承自Node - /// 资源标识符 - /// 是否创建副本,默认为false - /// 创建资源实例的工厂函数 - public Func GetOrRegisterResourceFactory(AssetCatalog.ResourceId id, bool duplicate = false) - where T : Resource; + /// 节点类型,必须继承自Node + /// 模板资源标识符 + /// 创建模板实例的工厂函数 + Func GetOrRegisterTemplateFactory( + AssetCatalog.TemplateId id + ) where T : Node; + + /// + /// 获取或注册通用资产工厂函数 + /// + /// 资源类型,必须继承自Resource + /// 资产资源标识符 + /// 是否对原始资源进行复制操作,默认为false + /// 创建资产实例的工厂函数 + Func GetOrRegisterAssetFactory( + AssetCatalog.AssetId id, + bool duplicate = false + ) where T : Resource; /// /// 预加载指定路径的多个资源 diff --git a/GFramework.Godot/system/ResourceLoadSystem.cs b/GFramework.Godot/system/ResourceLoadSystem.cs index 728858e..8daaaad 100644 --- a/GFramework.Godot/system/ResourceLoadSystem.cs +++ b/GFramework.Godot/system/ResourceLoadSystem.cs @@ -1,4 +1,5 @@ using GFramework.Core.system; +using GFramework.Game.assets; using Godot; namespace GFramework.Godot.system; @@ -85,9 +86,7 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem } #endregion - - #region 场景实例化 - + /// /// 根据给定路径加载场景,并创建其节点实例。 /// @@ -100,16 +99,7 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem return scene.Instantiate(); } - /// - /// 注册或获取一个用于创建特定场景实例的工厂函数。 - /// 如果已存在相同路径的工厂函数,则尝试转换后复用。 - /// - /// 目标场景根节点的类型。 - /// 场景文件的id。 - /// 用于创建该场景实例的Func委托。 - /// 当已有工厂不是Func<T>类型时抛出。 - /// 当无法加载场景或实例化失败时抛出。 - public Func GetOrRegisterSceneFactory(AssetCatalog.SceneId id) where T : Node + public Func GetOrRegisterGameUnitFactory(AssetCatalog.GameUnitId id) where T : Node { var path = id.Path; if (_sceneFactories.TryGetValue(path, out var d)) @@ -129,22 +119,27 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem return factory; } - #endregion + public Func GetOrRegisterTemplateFactory(AssetCatalog.TemplateId id) where T : Node + { + var path = id.Path; + if (_sceneFactories.TryGetValue(path, out var d)) + return d as Func ?? + throw new InvalidCastException($"Factory for path '{path}' is not of type Func<{typeof(T)}>"); - #region 资源工厂 + var factory = () => + { + var scene = GetSceneLoader(path).Value + ?? throw new InvalidOperationException($"Scene not loaded: {path}"); - /// - /// 注册或获取一个用于加载或复制资源的工厂函数。 - /// 可选择是否每次调用都返回副本(Duplicate),适用于需要独立状态的资源。 - /// - /// 资源的具体类型。 - /// 资源文件的id。 - /// 是否每次都返回资源的一个副本,默认为false。 - /// 用于加载或复制资源的Func委托。 - /// 当已有工厂不是Func<T>类型时抛出。 - /// 当资源加载失败时抛出。 - public Func GetOrRegisterResourceFactory(AssetCatalog.ResourceId id, bool duplicate = false) - where T : Resource + return scene.Instantiate() + ?? throw new InvalidOperationException($"Instantiate failed: {path}"); + }; + + _sceneFactories[path] = factory; + return factory; + } + + public Func GetOrRegisterAssetFactory(AssetCatalog.AssetId id, bool duplicate = false) where T : Resource { var path = id.Path; if (_resourceFactories.TryGetValue(path, out var d)) @@ -164,9 +159,6 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem _resourceFactories[path] = factory; return factory; } - - #endregion - #region 缓存管理 ///