mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(ecs): 将ECS系统重构为Arch适配器模式
- 移除原有的ECS基础实现和接口定义 - 添加ArchEcsModule作为新的ECS模块实现 - 创建ArchSystemAdapter基类用于桥接Arch系统 - 修改MovementSystem继承ArchSystemAdapter适配新架构 - 更新ServiceModuleManager使用新的ArchECS模块 - 移除ArchitectureContext中的ECS相关方法 - 从项目中移除对Arch包的直接依赖引用
This commit is contained in:
parent
3675666e13
commit
d7bd9fc569
@ -25,7 +25,6 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Arch" Version="2.1.0"/>
|
|
||||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
using GFramework.Core.Abstractions.ecs;
|
|
||||||
using GFramework.Core.Abstractions.environment;
|
using GFramework.Core.Abstractions.environment;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.model;
|
using GFramework.Core.Abstractions.model;
|
||||||
@ -206,18 +205,4 @@ public interface IArchitectureContext
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>环境对象实例</returns>
|
/// <returns>环境对象实例</returns>
|
||||||
IEnvironment GetEnvironment();
|
IEnvironment GetEnvironment();
|
||||||
|
|
||||||
// === ECS 支持 ===
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取ECS世界实例
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>ECS世界实例</returns>
|
|
||||||
IEcsWorld GetEcsWorld();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册ECS系统
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">ECS系统类型</typeparam>
|
|
||||||
void RegisterEcsSystem<T>() where T : class, IEcsSystem;
|
|
||||||
}
|
}
|
||||||
@ -1,20 +0,0 @@
|
|||||||
using GFramework.Core.Abstractions.system;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.ecs;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS系统接口,继承自ISystem以集成到现有架构
|
|
||||||
/// </summary>
|
|
||||||
public interface IEcsSystem : ISystem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 系统优先级,数值越小越先执行
|
|
||||||
/// </summary>
|
|
||||||
int Priority { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 每帧更新
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime">帧间隔时间(秒)</param>
|
|
||||||
void Update(float deltaTime);
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
using Arch.Core;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.ecs;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS世界接口,封装Arch的World实例
|
|
||||||
/// </summary>
|
|
||||||
public interface IEcsWorld : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 当前实体数量
|
|
||||||
/// </summary>
|
|
||||||
int EntityCount { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取内部的Arch World实例(用于高级操作)
|
|
||||||
/// </summary>
|
|
||||||
World InternalWorld { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建一个新实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="types">组件类型数组</param>
|
|
||||||
/// <returns>创建的实体</returns>
|
|
||||||
Entity CreateEntity(params ComponentType[] types);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁指定实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">要销毁的实体</param>
|
|
||||||
void DestroyEntity(Entity entity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查实体是否存活
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">要检查的实体</param>
|
|
||||||
/// <returns>实体是否存活</returns>
|
|
||||||
bool IsAlive(Entity entity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清空所有实体
|
|
||||||
/// </summary>
|
|
||||||
void Clear();
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
using GFramework.Core.Abstractions.architecture;
|
using GFramework.Core.Abstractions.architecture;
|
||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
using GFramework.Core.Abstractions.ecs;
|
|
||||||
using GFramework.Core.Abstractions.environment;
|
using GFramework.Core.Abstractions.environment;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.ioc;
|
using GFramework.Core.Abstractions.ioc;
|
||||||
@ -413,29 +412,4 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ECS Support
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取ECS世界实例
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>ECS世界实例</returns>
|
|
||||||
public IEcsWorld GetEcsWorld()
|
|
||||||
{
|
|
||||||
var ecsWorld = GetOrCache<IEcsWorld>();
|
|
||||||
return ecsWorld ??
|
|
||||||
throw new InvalidOperationException("ECS World not initialized. Enable ECS in configuration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册ECS系统
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">ECS系统类型</typeparam>
|
|
||||||
public void RegisterEcsSystem<T>() where T : class, IEcsSystem
|
|
||||||
{
|
|
||||||
// 使用RegisterPlurality注册到所有接口
|
|
||||||
_container.RegisterPlurality<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
114
GFramework.Core/ecs/ArchEcsModule.cs
Normal file
114
GFramework.Core/ecs/ArchEcsModule.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
using GFramework.Core.Abstractions.architecture;
|
||||||
|
using GFramework.Core.Abstractions.ioc;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Arch ECS 模块 - 核心适配器,桥接 Arch 到框架生命周期
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ArchEcsModule : IServiceModule
|
||||||
|
{
|
||||||
|
private readonly List<ArchSystemAdapter<float>> _systems = [];
|
||||||
|
private IIocContainer? _container;
|
||||||
|
private World? _world;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enabled">是否启用模块</param>
|
||||||
|
public ArchEcsModule(bool enabled = true)
|
||||||
|
{
|
||||||
|
IsEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模块名称
|
||||||
|
/// </summary>
|
||||||
|
public string ModuleName => nameof(ArchEcsModule);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模块优先级
|
||||||
|
/// </summary>
|
||||||
|
public int Priority => 50;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEnabled { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册服务 - 创建并注册 World
|
||||||
|
/// </summary>
|
||||||
|
public void Register(IIocContainer container)
|
||||||
|
{
|
||||||
|
if (!IsEnabled) return;
|
||||||
|
|
||||||
|
_container = container;
|
||||||
|
|
||||||
|
// 创建并注册 World
|
||||||
|
_world = World.Create();
|
||||||
|
container.Register(_world);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化 - 从容器获取所有适配器并初始化
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
if (!IsEnabled || _world == null || _container == null) return;
|
||||||
|
|
||||||
|
// 从容器获取所有适配器
|
||||||
|
var adapters = _container.GetAll<ArchSystemAdapter<float>>();
|
||||||
|
if (adapters.Count > 0)
|
||||||
|
{
|
||||||
|
_systems.AddRange(adapters);
|
||||||
|
|
||||||
|
// 初始化所有系统(会调用 Arch 系统的 Initialize)
|
||||||
|
foreach (var system in _systems)
|
||||||
|
{
|
||||||
|
system.Initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步销毁
|
||||||
|
/// </summary>
|
||||||
|
public async ValueTask DestroyAsync()
|
||||||
|
{
|
||||||
|
if (!IsEnabled) return;
|
||||||
|
|
||||||
|
// 销毁所有系统
|
||||||
|
foreach (var system in _systems)
|
||||||
|
{
|
||||||
|
system.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
_systems.Clear();
|
||||||
|
|
||||||
|
// 销毁 World
|
||||||
|
if (_world != null)
|
||||||
|
{
|
||||||
|
World.Destroy(_world);
|
||||||
|
_world = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ValueTask.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新所有 ECS 系统
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">帧间隔时间</param>
|
||||||
|
public void Update(float deltaTime)
|
||||||
|
{
|
||||||
|
if (!IsEnabled) return;
|
||||||
|
|
||||||
|
// 调用所有系统的更新
|
||||||
|
foreach (var system in _systems)
|
||||||
|
{
|
||||||
|
system.Update(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
136
GFramework.Core/ecs/ArchSystemAdapter.cs
Normal file
136
GFramework.Core/ecs/ArchSystemAdapter.cs
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
using GFramework.Core.extensions;
|
||||||
|
using GFramework.Core.system;
|
||||||
|
using ArchSys = Arch.System;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Arch 系统适配器 - 桥接 Arch.System.ISystem<T> 到框架上下文
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">系统数据类型(通常是 float 表示 deltaTime)</typeparam>
|
||||||
|
public abstract class ArchSystemAdapter<T> : AbstractSystem, ArchSys.ISystem<T>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置 Arch ECS 世界的实例
|
||||||
|
/// </summary>
|
||||||
|
public World World { get; private set; } = null!;
|
||||||
|
|
||||||
|
// ===== Arch 显式接口实现 =====
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显式实现 Arch.System.ISystem<T> 的初始化方法
|
||||||
|
/// 调用受保护的虚方法 OnArchInitialize 以允许子类自定义初始化逻辑
|
||||||
|
/// </summary>
|
||||||
|
void ArchSys.ISystem<T>.Initialize()
|
||||||
|
{
|
||||||
|
OnArchInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显式实现 Arch.System.ISystem<T> 的更新前回调方法
|
||||||
|
/// 调用受保护的虚方法 OnBeforeUpdate 以允许子类自定义预处理逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">系统数据参数(通常是 deltaTime)</param>
|
||||||
|
void ArchSys.ISystem<T>.BeforeUpdate(in T t)
|
||||||
|
{
|
||||||
|
OnBeforeUpdate(in t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显式实现 Arch.System.ISystem<T> 的主更新方法
|
||||||
|
/// 调用受保护的抽象方法 OnUpdate 以强制子类实现核心更新逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">系统数据参数(通常是 deltaTime)</param>
|
||||||
|
public void Update(in T t)
|
||||||
|
{
|
||||||
|
OnUpdate(in t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显式实现 Arch.System.ISystem<T> 的更新后回调方法
|
||||||
|
/// 调用受保护的虚方法 OnAfterUpdate 以允许子类自定义后处理逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">系统数据参数(通常是 deltaTime)</param>
|
||||||
|
void ArchSys.ISystem<T>.AfterUpdate(in T t)
|
||||||
|
{
|
||||||
|
OnAfterUpdate(in t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显式实现 IDisposable 的资源释放方法
|
||||||
|
/// 调用受保护的虚方法 OnArchDispose 以允许子类自定义资源清理逻辑
|
||||||
|
/// </summary>
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
OnArchDispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== GFramework 生命周期 =====
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统初始化方法
|
||||||
|
/// 在此方法中获取 Arch World 实例并调用 Arch 系统的初始化逻辑
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
World = this.GetService<World>()!;
|
||||||
|
|
||||||
|
// 调用 Arch 初始化
|
||||||
|
((ArchSys.ISystem<T>)this).Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统销毁方法
|
||||||
|
/// 在此方法中调用 Arch 系统的资源释放逻辑
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnDestroy()
|
||||||
|
{
|
||||||
|
((ArchSys.ISystem<T>)this).Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 子类可重写 Hook =====
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Arch 系统初始化的受保护虚方法
|
||||||
|
/// 子类可重写此方法以实现自定义的 Arch 系统初始化逻辑
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnArchInitialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新前处理的受保护虚方法
|
||||||
|
/// 子类可重写此方法以实现自定义的预处理逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">系统数据参数(通常是 deltaTime)</param>
|
||||||
|
protected virtual void OnBeforeUpdate(in T t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 核心更新逻辑的受保护抽象方法
|
||||||
|
/// 子类必须重写此方法以实现具体的系统更新功能
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">系统数据参数(通常是 deltaTime)</param>
|
||||||
|
protected virtual void OnUpdate(in T t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新后处理的受保护虚方法
|
||||||
|
/// 子类可重写此方法以实现自定义的后处理逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">系统数据参数(通常是 deltaTime)</param>
|
||||||
|
protected virtual void OnAfterUpdate(in T t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Arch 系统资源释放的受保护虚方法
|
||||||
|
/// 子类可重写此方法以实现自定义的资源清理逻辑
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnArchDispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,63 +0,0 @@
|
|||||||
using Arch.Core;
|
|
||||||
using GFramework.Core.Abstractions.ecs;
|
|
||||||
using GFramework.Core.extensions;
|
|
||||||
using GFramework.Core.system;
|
|
||||||
|
|
||||||
namespace GFramework.Core.ecs;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS系统基类,继承自AbstractSystem以集成到现有架构
|
|
||||||
/// </summary>
|
|
||||||
public abstract class EcsSystemBase : AbstractSystem, IEcsSystem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ECS世界实例
|
|
||||||
/// </summary>
|
|
||||||
protected IEcsWorld EcsWorld { get; private set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 快捷访问内部World
|
|
||||||
/// </summary>
|
|
||||||
protected World World => EcsWorld.InternalWorld;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统优先级,默认为0
|
|
||||||
/// </summary>
|
|
||||||
public virtual int Priority => 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 每帧更新(子类实现)
|
|
||||||
/// </summary>
|
|
||||||
public abstract void Update(float deltaTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统初始化
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnInit()
|
|
||||||
{
|
|
||||||
EcsWorld = this.GetService<IEcsWorld>() ?? throw new InvalidOperationException(
|
|
||||||
"EcsWorld not found in context. Make sure ECS is properly initialized.");
|
|
||||||
|
|
||||||
OnEcsInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统销毁
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnDestroy()
|
|
||||||
{
|
|
||||||
OnEcsDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS系统初始化(子类实现)
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void OnEcsInit();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS系统销毁(子类可选实现)
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void OnEcsDestroy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
using GFramework.Core.Abstractions.ecs;
|
|
||||||
using GFramework.Core.extensions;
|
|
||||||
using GFramework.Core.system;
|
|
||||||
|
|
||||||
namespace GFramework.Core.ecs;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS系统调度器,负责管理和更新所有ECS系统
|
|
||||||
/// </summary>
|
|
||||||
public sealed class EcsSystemRunner : AbstractSystem
|
|
||||||
{
|
|
||||||
private readonly List<IEcsSystem> _systems = new();
|
|
||||||
private bool _isRunning;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化调度器,从DI容器获取所有ECS系统
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnInit()
|
|
||||||
{
|
|
||||||
// 从容器获取所有已注册的ECS系统
|
|
||||||
var systemsList = this.GetService<IReadOnlyList<IEcsSystem>>();
|
|
||||||
if (systemsList is { Count: > 0 })
|
|
||||||
{
|
|
||||||
// 按优先级排序
|
|
||||||
_systems.AddRange(systemsList.OrderBy(s => s.Priority));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新所有ECS系统
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime">帧间隔时间</param>
|
|
||||||
public void Update(float deltaTime)
|
|
||||||
{
|
|
||||||
if (!_isRunning) return;
|
|
||||||
|
|
||||||
foreach (var system in _systems)
|
|
||||||
{
|
|
||||||
system.Update(deltaTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 启动调度器
|
|
||||||
/// </summary>
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
_isRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 停止调度器
|
|
||||||
/// </summary>
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
_isRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁调度器
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnDestroy()
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
_systems.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
using Arch.Core;
|
|
||||||
using GFramework.Core.Abstractions.ecs;
|
|
||||||
|
|
||||||
namespace GFramework.Core.ecs;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS世界实现,封装Arch的World实例
|
|
||||||
/// </summary>
|
|
||||||
public sealed class EcsWorld : IEcsWorld
|
|
||||||
{
|
|
||||||
private bool _disposed;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取内部的Arch World实例
|
|
||||||
/// </summary>
|
|
||||||
public World InternalWorld { get; } = World.Create();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前实体数量
|
|
||||||
/// </summary>
|
|
||||||
public int EntityCount => InternalWorld.Size;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建一个新实体
|
|
||||||
/// </summary>
|
|
||||||
public Entity CreateEntity(params ComponentType[] types)
|
|
||||||
{
|
|
||||||
return InternalWorld.Create(types);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁指定实体
|
|
||||||
/// </summary>
|
|
||||||
public void DestroyEntity(Entity entity)
|
|
||||||
{
|
|
||||||
InternalWorld.Destroy(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查实体是否存活
|
|
||||||
/// </summary>
|
|
||||||
public bool IsAlive(Entity entity)
|
|
||||||
{
|
|
||||||
return InternalWorld.IsAlive(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清空所有实体
|
|
||||||
/// </summary>
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
InternalWorld.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放资源
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_disposed) return;
|
|
||||||
|
|
||||||
World.Destroy(InternalWorld);
|
|
||||||
_disposed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,37 +4,33 @@ using GFramework.Core.ecs.components;
|
|||||||
namespace GFramework.Core.ecs.systems;
|
namespace GFramework.Core.ecs.systems;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 移动系统,负责更新具有位置和速度组件的实体的位置。
|
/// 移动系统 - Arch 原生实现
|
||||||
/// 根据速度和时间增量计算实体的新位置。
|
/// 负责更新具有位置和速度组件的实体的位置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MovementSystem : EcsSystemBase
|
public sealed class MovementSystem : ArchSystemAdapter<float>
|
||||||
{
|
{
|
||||||
private QueryDescription _query;
|
private QueryDescription _query;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取系统的优先级,数值越小优先级越高。
|
/// 初始化系统
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override int Priority => 0;
|
public void Initialize(World world)
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS初始化回调方法,在系统初始化时调用。
|
|
||||||
/// 创建查询描述符,用于查找同时拥有Position和Velocity组件的实体。
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnEcsInit()
|
|
||||||
{
|
{
|
||||||
// 创建查询:查找所有同时拥有Position和Velocity组件的实体
|
// 创建查询:查找所有同时拥有Position和Velocity组件的实体
|
||||||
_query = new QueryDescription()
|
_query = new QueryDescription()
|
||||||
.WithAll<Position, Velocity>();
|
.WithAll<Position, Velocity>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 系统更新方法,每帧调用一次。
|
/// 系统更新方法,每帧调用一次
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="deltaTime">帧间隔时间,用于计算位置变化量</param>
|
/// <param name="world">ECS 世界</param>
|
||||||
public override void Update(float deltaTime)
|
/// <param name="deltaTime">帧间隔时间</param>
|
||||||
|
public void Update(World world, float deltaTime)
|
||||||
{
|
{
|
||||||
// 查询并更新所有符合条件的实体
|
// 查询并更新所有符合条件的实体
|
||||||
World.Query(in _query, (ref Position pos, ref Velocity vel) =>
|
world.Query(in _query, (ref Position pos, ref Velocity vel) =>
|
||||||
{
|
{
|
||||||
pos.X += vel.X * deltaTime;
|
pos.X += vel.X * deltaTime;
|
||||||
pos.Y += vel.Y * deltaTime;
|
pos.Y += vel.Y * deltaTime;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using GFramework.Core.Abstractions.ioc;
|
|||||||
using GFramework.Core.Abstractions.lifecycle;
|
using GFramework.Core.Abstractions.lifecycle;
|
||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.logging;
|
||||||
using GFramework.Core.Abstractions.properties;
|
using GFramework.Core.Abstractions.properties;
|
||||||
|
using GFramework.Core.ecs;
|
||||||
using GFramework.Core.logging;
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.services.modules;
|
using GFramework.Core.services.modules;
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ public sealed class ServiceModuleManager : IServiceModuleManager
|
|||||||
|
|
||||||
if (properties.EnableEcs)
|
if (properties.EnableEcs)
|
||||||
{
|
{
|
||||||
RegisterModule(new EcsServiceModule(enabled: true));
|
RegisterModule(new ArchEcsModule(enabled: true));
|
||||||
_logger.Info("ECS module enabled via configuration");
|
_logger.Info("ECS module enabled via configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
using GFramework.Core.Abstractions.architecture;
|
|
||||||
using GFramework.Core.Abstractions.ecs;
|
|
||||||
using GFramework.Core.Abstractions.ioc;
|
|
||||||
using GFramework.Core.Abstractions.lifecycle;
|
|
||||||
using GFramework.Core.ecs;
|
|
||||||
|
|
||||||
namespace GFramework.Core.services.modules;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ECS(Entity Component System)模块,用于注册、初始化和管理ECS相关服务。
|
|
||||||
/// 该模块负责创建ECS世界和系统运行器,并将其注册到依赖注入容器中。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class EcsServiceModule : IServiceModule
|
|
||||||
{
|
|
||||||
private EcsSystemRunner? _ecsRunner;
|
|
||||||
|
|
||||||
private EcsWorld? _ecsWorld;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造函数,初始化ECS模块。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="enabled">指定模块是否启用,默认为 true。</param>
|
|
||||||
public EcsServiceModule(bool enabled = true)
|
|
||||||
{
|
|
||||||
IsEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取模块名称。
|
|
||||||
/// </summary>
|
|
||||||
public string ModuleName => nameof(EcsServiceModule);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取模块优先级,数值越小优先级越高。
|
|
||||||
/// </summary>
|
|
||||||
public int Priority => 100;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取模块启用状态。
|
|
||||||
/// </summary>
|
|
||||||
public bool IsEnabled { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册ECS相关服务到依赖注入容器中。
|
|
||||||
/// 包括ECS世界实例和系统运行器实例的注册。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="container">依赖注入容器实例。</param>
|
|
||||||
public void Register(IIocContainer container)
|
|
||||||
{
|
|
||||||
if (!IsEnabled) return;
|
|
||||||
|
|
||||||
_ecsWorld = new EcsWorld();
|
|
||||||
container.Register(_ecsWorld);
|
|
||||||
container.Register<IEcsWorld>(_ecsWorld);
|
|
||||||
|
|
||||||
container.RegisterPlurality<EcsSystemRunner>();
|
|
||||||
_ecsRunner = container.Get<EcsSystemRunner>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化ECS模块。
|
|
||||||
/// 如果系统运行器实现了IInitializable接口,则调用其初始化方法。
|
|
||||||
/// </summary>
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
if (!IsEnabled || _ecsRunner == null) return;
|
|
||||||
|
|
||||||
if (_ecsRunner is IInitializable initializable)
|
|
||||||
{
|
|
||||||
initializable.Initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步销毁ECS模块并释放相关资源。
|
|
||||||
/// 包括销毁系统运行器和释放ECS世界资源。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>表示异步操作完成的任务。</returns>
|
|
||||||
public async ValueTask DestroyAsync()
|
|
||||||
{
|
|
||||||
if (!IsEnabled) return;
|
|
||||||
|
|
||||||
if (_ecsRunner is IDestroyable destroyable)
|
|
||||||
{
|
|
||||||
destroyable.Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
_ecsRunner = null;
|
|
||||||
|
|
||||||
if (_ecsWorld != null)
|
|
||||||
{
|
|
||||||
_ecsWorld.Dispose();
|
|
||||||
_ecsWorld = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
await ValueTask.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取ECS世界实例。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>ECS世界实例,如果未启用则返回 null。</returns>
|
|
||||||
public IEcsWorld? GetEcsWorld() => _ecsWorld;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取ECS系统运行器实例(内部使用)。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>ECS系统运行器实例,如果未启用则返回 null。</returns>
|
|
||||||
internal EcsSystemRunner? GetEcsRunner() => _ecsRunner;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user