diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 628753b..8ec0bef 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -125,6 +125,15 @@ jobs:
--no-build \
--logger "trx;LogFileName=sg-$RANDOM.trx" \
--results-directory TestResults
+
+ - name: Test - GFramework.Ecs.Arch.Tests
+ run: |
+ dotnet test GFramework.Ecs.Arch.Tests \
+ -c Release \
+ --no-build \
+ --logger "trx;LogFileName=ecs-arch-$RANDOM.trx" \
+ --results-directory TestResults
+
- name: Generate CTRF report
run: |
mkdir -p ctrf
diff --git a/GFramework.Core.Abstractions/architecture/ArchitectureModuleRegistry.cs b/GFramework.Core.Abstractions/architecture/ArchitectureModuleRegistry.cs
new file mode 100644
index 0000000..ab5a7c3
--- /dev/null
+++ b/GFramework.Core.Abstractions/architecture/ArchitectureModuleRegistry.cs
@@ -0,0 +1,42 @@
+using System.Collections.Concurrent;
+
+namespace GFramework.Core.Abstractions.architecture;
+
+///
+/// 架构模块注册表 - 用于外部模块的自动注册
+///
+public static class ArchitectureModuleRegistry
+{
+ private static readonly ConcurrentDictionary> _factories = new();
+
+ ///
+ /// 注册模块工厂(幂等操作,相同模块名只会注册一次)
+ ///
+ /// 模块工厂函数
+ public static void Register(Func factory)
+ {
+ // 创建临时实例以获取模块名(用于幂等性检查)
+ var tempModule = factory();
+ var moduleName = tempModule.ModuleName;
+
+ // 幂等注册:相同模块名只注册一次
+ _factories.TryAdd(moduleName, factory);
+ }
+
+ ///
+ /// 创建所有已注册的模块实例
+ ///
+ /// 模块实例集合
+ public static IEnumerable CreateModules()
+ {
+ return _factories.Values.Select(f => f());
+ }
+
+ ///
+ /// 清空注册表(主要用于测试)
+ ///
+ public static void Clear()
+ {
+ _factories.Clear();
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Core.Abstractions/architecture/IServiceModuleManager.cs b/GFramework.Core.Abstractions/architecture/IServiceModuleManager.cs
index 20b7d52..8c7face 100644
--- a/GFramework.Core.Abstractions/architecture/IServiceModuleManager.cs
+++ b/GFramework.Core.Abstractions/architecture/IServiceModuleManager.cs
@@ -1,5 +1,4 @@
using GFramework.Core.Abstractions.ioc;
-using GFramework.Core.Abstractions.properties;
namespace GFramework.Core.Abstractions.architecture;
@@ -18,8 +17,7 @@ public interface IServiceModuleManager
/// 注册内置的服务模块。
///
/// IoC容器实例,用于解析依赖。
- /// 架构属性配置,用于模块初始化。
- void RegisterBuiltInModules(IIocContainer container, ArchitectureProperties properties);
+ void RegisterBuiltInModules(IIocContainer container);
///
/// 获取所有已注册的服务模块。
diff --git a/GFramework.Core.Abstractions/properties/ArchitectureProperties.cs b/GFramework.Core.Abstractions/properties/ArchitectureProperties.cs
index 1915685..f1a5eca 100644
--- a/GFramework.Core.Abstractions/properties/ArchitectureProperties.cs
+++ b/GFramework.Core.Abstractions/properties/ArchitectureProperties.cs
@@ -17,10 +17,4 @@ public sealed class ArchitectureProperties
/// 默认值为 false,表示不启用严格验证。
///
public bool StrictPhaseValidation { get; set; }
-
- ///
- /// 启用 ECS(Entity Component System)功能的开关。
- /// 当设置为 true 时,架构将启用 ECS 相关功能。
- ///
- public bool EnableEcs { get; set; }
}
\ No newline at end of file
diff --git a/GFramework.Core.Tests/GFramework.Core.Tests.csproj b/GFramework.Core.Tests/GFramework.Core.Tests.csproj
index eed0620..f394be1 100644
--- a/GFramework.Core.Tests/GFramework.Core.Tests.csproj
+++ b/GFramework.Core.Tests/GFramework.Core.Tests.csproj
@@ -1,9 +1,11 @@
+ net8.0;net10.0
disable
enable
- net10.0;net8.0
+ false
+ true
diff --git a/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs b/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs
index efe5aad..5621b33 100644
--- a/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs
+++ b/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs
@@ -4,7 +4,6 @@ using GFramework.Core.Abstractions.environment;
using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.model;
-using GFramework.Core.Abstractions.properties;
using GFramework.Core.Abstractions.query;
using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
@@ -15,7 +14,6 @@ using GFramework.Core.events;
using GFramework.Core.ioc;
using GFramework.Core.query;
using Mediator;
-using NUnit.Framework;
using ICommand = GFramework.Core.Abstractions.command.ICommand;
namespace GFramework.Core.Tests.architecture;
@@ -48,8 +46,7 @@ public class ArchitectureServicesTests
private void RegisterBuiltInServices()
{
- var properties = new ArchitectureProperties();
- _services!.ModuleManager.RegisterBuiltInModules(_services.Container, properties);
+ _services!.ModuleManager.RegisterBuiltInModules(_services.Container);
}
///
@@ -216,13 +213,11 @@ public class ArchitectureServicesTests
[Test]
public void Multiple_Instances_Should_Have_Independent_EventBus()
{
- var properties = new ArchitectureProperties();
-
var services1 = new ArchitectureServices();
- services1.ModuleManager.RegisterBuiltInModules(services1.Container, properties);
+ services1.ModuleManager.RegisterBuiltInModules(services1.Container);
var services2 = new ArchitectureServices();
- services2.ModuleManager.RegisterBuiltInModules(services2.Container, properties);
+ services2.ModuleManager.RegisterBuiltInModules(services2.Container);
Assert.That(services1.EventBus, Is.Not.SameAs(services2.EventBus));
}
@@ -233,13 +228,11 @@ public class ArchitectureServicesTests
[Test]
public void Multiple_Instances_Should_Have_Independent_CommandBus()
{
- var properties = new ArchitectureProperties();
-
var services1 = new ArchitectureServices();
- services1.ModuleManager.RegisterBuiltInModules(services1.Container, properties);
+ services1.ModuleManager.RegisterBuiltInModules(services1.Container);
var services2 = new ArchitectureServices();
- services2.ModuleManager.RegisterBuiltInModules(services2.Container, properties);
+ services2.ModuleManager.RegisterBuiltInModules(services2.Container);
Assert.That(services1.CommandExecutor, Is.Not.SameAs(services2.CommandExecutor));
}
@@ -250,13 +243,11 @@ public class ArchitectureServicesTests
[Test]
public void Multiple_Instances_Should_Have_Independent_QueryBus()
{
- var properties = new ArchitectureProperties();
-
var services1 = new ArchitectureServices();
- services1.ModuleManager.RegisterBuiltInModules(services1.Container, properties);
+ services1.ModuleManager.RegisterBuiltInModules(services1.Container);
var services2 = new ArchitectureServices();
- services2.ModuleManager.RegisterBuiltInModules(services2.Container, properties);
+ services2.ModuleManager.RegisterBuiltInModules(services2.Container);
Assert.That(services1.QueryExecutor, Is.Not.SameAs(services2.QueryExecutor));
}
@@ -269,27 +260,6 @@ public class ArchitectureServicesTests
{
Assert.That(_services!.ModuleManager, Is.Not.Null);
}
-
- ///
- /// 测试EnableEcs配置开关
- ///
- [Test]
- public void EnableEcs_Should_Control_Ecs_Module_Registration()
- {
- var propertiesWithEcs = new ArchitectureProperties { EnableEcs = true };
- var propertiesWithoutEcs = new ArchitectureProperties { EnableEcs = false };
-
- var servicesWithEcs = new ArchitectureServices();
- servicesWithEcs.ModuleManager.RegisterBuiltInModules(servicesWithEcs.Container, propertiesWithEcs);
-
- var servicesWithoutEcs = new ArchitectureServices();
- servicesWithoutEcs.ModuleManager.RegisterBuiltInModules(servicesWithoutEcs.Container, propertiesWithoutEcs);
-
- var modulesWithEcs = servicesWithEcs.ModuleManager.GetModules();
- var modulesWithoutEcs = servicesWithoutEcs.ModuleManager.GetModules();
-
- Assert.That(modulesWithEcs.Count, Is.GreaterThan(modulesWithoutEcs.Count));
- }
}
#region Test Classes
diff --git a/GFramework.Core/GFramework.Core.csproj b/GFramework.Core/GFramework.Core.csproj
index 05baa84..41e4b38 100644
--- a/GFramework.Core/GFramework.Core.csproj
+++ b/GFramework.Core/GFramework.Core.csproj
@@ -13,7 +13,5 @@
-
-
diff --git a/GFramework.Core/architecture/Architecture.cs b/GFramework.Core/architecture/Architecture.cs
index 717c17e..0ebdff6 100644
--- a/GFramework.Core/architecture/Architecture.cs
+++ b/GFramework.Core/architecture/Architecture.cs
@@ -641,8 +641,8 @@ public abstract class Architecture(
_logger = LoggerFactoryResolver.Provider.CreateLogger(GetType().Name);
Environment.Initialize();
- // 注册内置服务模块(根据配置)
- Services.ModuleManager.RegisterBuiltInModules(Container, Configuration.ArchitectureProperties);
+ // 注册内置服务模块
+ Services.ModuleManager.RegisterBuiltInModules(Container);
// 将 Environment 注册到容器(如果尚未注册)
if (!Container.Contains())
diff --git a/GFramework.Core/services/ServiceModuleManager.cs b/GFramework.Core/services/ServiceModuleManager.cs
index 0f16073..9ed0aac 100644
--- a/GFramework.Core/services/ServiceModuleManager.cs
+++ b/GFramework.Core/services/ServiceModuleManager.cs
@@ -2,8 +2,6 @@ using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.lifecycle;
using GFramework.Core.Abstractions.logging;
-using GFramework.Core.Abstractions.properties;
-using GFramework.Core.ecs;
using GFramework.Core.logging;
using GFramework.Core.services.modules;
@@ -44,12 +42,11 @@ public sealed class ServiceModuleManager : IServiceModuleManager
///
/// 注册内置服务模块,并根据优先级排序后完成服务注册。
- /// 内置模块包括事件总线、命令执行器、查询执行器等核心模块,
- /// 并根据配置决定是否启用ECS模块。
+ /// 内置模块包括事件总线、命令执行器、查询执行器等核心模块。
+ /// 同时注册通过 ArchitectureModuleRegistry 自动注册的外部模块。
///
/// IoC容器实例,用于模块服务注册。
- /// 架构属性配置,用于判断是否启用ECS模块。
- public void RegisterBuiltInModules(IIocContainer container, ArchitectureProperties properties)
+ public void RegisterBuiltInModules(IIocContainer container)
{
if (_builtInModulesRegistered)
{
@@ -57,21 +54,25 @@ public sealed class ServiceModuleManager : IServiceModuleManager
return;
}
+ // 注册内置模块
RegisterModule(new EventBusModule());
RegisterModule(new CommandExecutorModule());
RegisterModule(new QueryExecutorModule());
RegisterModule(new AsyncQueryExecutorModule());
- if (properties.EnableEcs)
+ // 注册外部模块(通过 ArchitectureModuleRegistry 自动注册)
+ foreach (var module in ArchitectureModuleRegistry.CreateModules())
{
- RegisterModule(new ArchEcsModule(enabled: true));
- _logger.Info("ECS module enabled via configuration");
+ RegisterModule(module);
+ _logger.Info($"External module registered: {module.ModuleName}");
}
+ // 按优先级排序
var sortedModules = _modules.OrderBy(m => m.Priority).ToList();
_modules.Clear();
_modules.AddRange(sortedModules);
+ // 注册服务
foreach (var module in _modules.Where(module => module.IsEnabled))
{
_logger.Debug($"Registering services for module: {module.ModuleName}");
@@ -79,7 +80,7 @@ public sealed class ServiceModuleManager : IServiceModuleManager
}
_builtInModulesRegistered = true;
- _logger.Info($"Registered {_modules.Count} built-in service modules");
+ _logger.Info($"Registered {_modules.Count} service modules");
}
///
diff --git a/GFramework.Ecs.Arch.Abstractions/ArchOptions.cs b/GFramework.Ecs.Arch.Abstractions/ArchOptions.cs
new file mode 100644
index 0000000..926f877
--- /dev/null
+++ b/GFramework.Ecs.Arch.Abstractions/ArchOptions.cs
@@ -0,0 +1,22 @@
+namespace GFramework.Ecs.Arch.Abstractions;
+
+///
+/// Arch ECS 配置选项
+///
+public sealed class ArchOptions
+{
+ ///
+ /// World 初始容量
+ ///
+ public int WorldCapacity { get; set; } = 1000;
+
+ ///
+ /// 是否启用统计信息
+ ///
+ public bool EnableStatistics { get; set; }
+
+ ///
+ /// 模块优先级
+ ///
+ public int Priority { get; set; } = 50;
+}
\ No newline at end of file
diff --git a/GFramework.Ecs.Arch.Abstractions/Directory.Build.props b/GFramework.Ecs.Arch.Abstractions/Directory.Build.props
new file mode 100644
index 0000000..8febdc4
--- /dev/null
+++ b/GFramework.Ecs.Arch.Abstractions/Directory.Build.props
@@ -0,0 +1,18 @@
+
+
+ netstandard2.1
+ true
+ true
+ preview
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
+
diff --git a/GFramework.Ecs.Arch.Abstractions/GFramework.Ecs.Arch.Abstractions.csproj b/GFramework.Ecs.Arch.Abstractions/GFramework.Ecs.Arch.Abstractions.csproj
new file mode 100644
index 0000000..b937843
--- /dev/null
+++ b/GFramework.Ecs.Arch.Abstractions/GFramework.Ecs.Arch.Abstractions.csproj
@@ -0,0 +1,13 @@
+
+
+
+ GeWuYou.$(AssemblyName)
+ true
+ enable
+
+
+
+
+
+
+
diff --git a/GFramework.Ecs.Arch.Abstractions/GlobalUsings.cs b/GFramework.Ecs.Arch.Abstractions/GlobalUsings.cs
new file mode 100644
index 0000000..9d7f7e7
--- /dev/null
+++ b/GFramework.Ecs.Arch.Abstractions/GlobalUsings.cs
@@ -0,0 +1,3 @@
+global using System;
+global using System.Collections.Generic;
+global using System.Threading.Tasks;
\ No newline at end of file
diff --git a/GFramework.Ecs.Arch.Abstractions/IArchEcsModule.cs b/GFramework.Ecs.Arch.Abstractions/IArchEcsModule.cs
new file mode 100644
index 0000000..6dcc631
--- /dev/null
+++ b/GFramework.Ecs.Arch.Abstractions/IArchEcsModule.cs
@@ -0,0 +1,15 @@
+using GFramework.Core.Abstractions.architecture;
+
+namespace GFramework.Ecs.Arch.Abstractions;
+
+///
+/// Arch ECS 模块接口 - 定义 ECS 模块的核心契约
+///
+public interface IArchEcsModule : IServiceModule
+{
+ ///
+ /// 更新所有 ECS 系统
+ ///
+ /// 帧间隔时间
+ void Update(float deltaTime);
+}
\ No newline at end of file
diff --git a/GFramework.Ecs.Arch.Abstractions/IArchSystemAdapter.cs b/GFramework.Ecs.Arch.Abstractions/IArchSystemAdapter.cs
new file mode 100644
index 0000000..59c42d6
--- /dev/null
+++ b/GFramework.Ecs.Arch.Abstractions/IArchSystemAdapter.cs
@@ -0,0 +1,16 @@
+using GFramework.Core.Abstractions.system;
+
+namespace GFramework.Ecs.Arch.Abstractions;
+
+///
+/// Arch 系统适配器接口 - 桥接 Arch.System.ISystem<T> 到框架上下文
+///
+/// 系统数据类型(通常是 float 表示 deltaTime)
+public interface IArchSystemAdapter : ISystem
+{
+ ///
+ /// 更新系统
+ ///
+ /// 系统数据参数(通常是 deltaTime)
+ void Update(in T t);
+}
\ No newline at end of file
diff --git a/GFramework.Ecs.Arch.Tests/GFramework.Ecs.Arch.Tests.csproj b/GFramework.Ecs.Arch.Tests/GFramework.Ecs.Arch.Tests.csproj
new file mode 100644
index 0000000..1d5346f
--- /dev/null
+++ b/GFramework.Ecs.Arch.Tests/GFramework.Ecs.Arch.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net8.0;net10.0
+ disable
+ enable
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GFramework.Ecs.Arch.Tests/GlobalUsings.cs b/GFramework.Ecs.Arch.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..170ef5b
--- /dev/null
+++ b/GFramework.Ecs.Arch.Tests/GlobalUsings.cs
@@ -0,0 +1,5 @@
+global using System;
+global using System.Collections.Generic;
+global using System.Threading.Tasks;
+global using NUnit.Framework;
+global using GFramework.Ecs.Arch;
\ No newline at end of file
diff --git a/GFramework.Core.Tests/ecs/EcsAdvancedTests.cs b/GFramework.Ecs.Arch.Tests/ecs/EcsAdvancedTests.cs
similarity index 97%
rename from GFramework.Core.Tests/ecs/EcsAdvancedTests.cs
rename to GFramework.Ecs.Arch.Tests/ecs/EcsAdvancedTests.cs
index 3831138..3ef8f07 100644
--- a/GFramework.Core.Tests/ecs/EcsAdvancedTests.cs
+++ b/GFramework.Ecs.Arch.Tests/ecs/EcsAdvancedTests.cs
@@ -2,13 +2,11 @@ using System.Diagnostics.CodeAnalysis;
using Arch.Core;
using GFramework.Core.Abstractions.rule;
using GFramework.Core.architecture;
-using GFramework.Core.ecs;
-using GFramework.Core.ecs.components;
-using GFramework.Core.ecs.systems;
using GFramework.Core.ioc;
-using NUnit.Framework;
+using GFramework.Ecs.Arch.components;
+using GFramework.Ecs.Arch.systems;
-namespace GFramework.Core.Tests.ecs;
+namespace GFramework.Ecs.Arch.Tests.ecs;
///
/// ECS 高级功能测试类 - 使用 Arch 原生 API
diff --git a/GFramework.Core.Tests/ecs/EcsBasicTests.cs b/GFramework.Ecs.Arch.Tests/ecs/EcsBasicTests.cs
similarity index 96%
rename from GFramework.Core.Tests/ecs/EcsBasicTests.cs
rename to GFramework.Ecs.Arch.Tests/ecs/EcsBasicTests.cs
index c1d9f52..896789a 100644
--- a/GFramework.Core.Tests/ecs/EcsBasicTests.cs
+++ b/GFramework.Ecs.Arch.Tests/ecs/EcsBasicTests.cs
@@ -2,13 +2,11 @@ using System.Diagnostics.CodeAnalysis;
using Arch.Core;
using GFramework.Core.Abstractions.rule;
using GFramework.Core.architecture;
-using GFramework.Core.ecs;
-using GFramework.Core.ecs.components;
-using GFramework.Core.ecs.systems;
using GFramework.Core.ioc;
-using NUnit.Framework;
+using GFramework.Ecs.Arch.components;
+using GFramework.Ecs.Arch.systems;
-namespace GFramework.Core.Tests.ecs;
+namespace GFramework.Ecs.Arch.Tests.ecs;
///
/// ECS 基础功能测试类 - 使用 Arch 原生 API
diff --git a/GFramework.Core.Tests/ecs/EcsIntegrationTests.cs b/GFramework.Ecs.Arch.Tests/ecs/EcsIntegrationTests.cs
similarity index 97%
rename from GFramework.Core.Tests/ecs/EcsIntegrationTests.cs
rename to GFramework.Ecs.Arch.Tests/ecs/EcsIntegrationTests.cs
index 55287a9..db9c290 100644
--- a/GFramework.Core.Tests/ecs/EcsIntegrationTests.cs
+++ b/GFramework.Ecs.Arch.Tests/ecs/EcsIntegrationTests.cs
@@ -2,13 +2,11 @@ using System.Diagnostics.CodeAnalysis;
using Arch.Core;
using GFramework.Core.Abstractions.rule;
using GFramework.Core.architecture;
-using GFramework.Core.ecs;
-using GFramework.Core.ecs.components;
-using GFramework.Core.ecs.systems;
using GFramework.Core.ioc;
-using NUnit.Framework;
+using GFramework.Ecs.Arch.components;
+using GFramework.Ecs.Arch.systems;
-namespace GFramework.Core.Tests.ecs;
+namespace GFramework.Ecs.Arch.Tests.ecs;
///
/// ECS 集成测试类 - 使用 Arch 原生 API
diff --git a/GFramework.Ecs.Arch.Tests/integration/ExplicitRegistrationTests.cs b/GFramework.Ecs.Arch.Tests/integration/ExplicitRegistrationTests.cs
new file mode 100644
index 0000000..515e5c9
--- /dev/null
+++ b/GFramework.Ecs.Arch.Tests/integration/ExplicitRegistrationTests.cs
@@ -0,0 +1,135 @@
+using Arch.Core;
+using GFramework.Core.Abstractions.architecture;
+using GFramework.Core.architecture;
+using GFramework.Core.ioc;
+using GFramework.Ecs.Arch.Abstractions;
+using GFramework.Ecs.Arch.extensions;
+
+namespace GFramework.Ecs.Arch.Tests.integration;
+
+///
+/// 显式注册集成测试
+///
+[TestFixture]
+public class ExplicitRegistrationTests
+{
+ [SetUp]
+ public void Setup()
+ {
+ _container = new MicrosoftDiContainer();
+ _context = new ArchitectureContext(_container);
+
+ // 清空注册表,确保测试隔离
+ ArchitectureModuleRegistry.Clear();
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ _container?.Clear();
+ _context = null;
+ ArchitectureModuleRegistry.Clear();
+ GameContext.Clear();
+ }
+
+ private MicrosoftDiContainer? _container;
+ private ArchitectureContext? _context;
+
+ ///
+ /// 测试 Arch ECS 模块显式注册
+ ///
+ [Test]
+ public void ArchEcsModule_Should_Be_Explicitly_Registered()
+ {
+ // Arrange
+ var architecture = new TestArchitecture();
+
+ // Act - 显式注册
+ architecture.UseArch();
+ architecture.Initialize();
+
+ // Assert - 验证 World 已注册(由 ArchEcsModule 注册)
+ var world = architecture.Context.GetService();
+ Assert.That(world, Is.Not.Null, "World should be registered by ArchEcsModule");
+
+ // 验证 IArchEcsModule 已注册
+ var ecsModule = architecture.Context.GetService();
+ Assert.That(ecsModule, Is.Not.Null, "IArchEcsModule should be registered");
+ }
+
+ ///
+ /// 测试 World 是否正确注册到容器
+ ///
+ [Test]
+ public void World_Should_Be_Registered_In_Container()
+ {
+ // Arrange
+ var architecture = new TestArchitecture();
+
+ // Act - 显式注册
+ architecture.UseArch();
+ architecture.Initialize();
+
+ // Assert
+ var world = architecture.Context.GetService();
+ Assert.That(world, Is.Not.Null, "World should be registered in container");
+ }
+
+ ///
+ /// 测试带配置的注册
+ ///
+ [Test]
+ public void UseArch_Should_Accept_Configuration()
+ {
+ // Arrange
+ var architecture = new TestArchitecture();
+ var configCalled = false;
+
+ // Act
+ architecture.UseArch(options =>
+ {
+ options.WorldCapacity = 2000;
+ options.EnableStatistics = true;
+ configCalled = true;
+ });
+
+ // Assert
+ Assert.That(configCalled, Is.True, "Configuration delegate should be called");
+ }
+
+ ///
+ /// 测试链式调用
+ ///
+ [Test]
+ public void UseArch_Should_Support_Chaining()
+ {
+ // Arrange & Act
+ var architecture = new TestArchitecture()
+ .UseArch()
+ .UseArch(options => options.WorldCapacity = 2000);
+
+ architecture.Initialize();
+
+ // Assert - 验证模块已注册
+ var world = architecture.Context.GetService();
+ Assert.That(world, Is.Not.Null, "World should be registered");
+
+ var ecsModule = architecture.Context.GetService();
+ Assert.That(ecsModule, Is.Not.Null, "IArchEcsModule should be registered");
+ }
+
+ ///
+ /// 测试架构类,用于测试
+ ///
+ private class TestArchitecture : Architecture
+ {
+ public TestArchitecture() : base(new ArchitectureConfiguration())
+ {
+ }
+
+ protected override void OnInitialize()
+ {
+ // 测试架构,无需额外初始化
+ }
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Core/ecs/ArchEcsModule.cs b/GFramework.Ecs.Arch/ArchEcsModule.cs
similarity index 72%
rename from GFramework.Core/ecs/ArchEcsModule.cs
rename to GFramework.Ecs.Arch/ArchEcsModule.cs
index 784b822..31ab8e9 100644
--- a/GFramework.Core/ecs/ArchEcsModule.cs
+++ b/GFramework.Ecs.Arch/ArchEcsModule.cs
@@ -1,25 +1,27 @@
using Arch.Core;
-using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.ioc;
-namespace GFramework.Core.ecs;
+namespace GFramework.Ecs.Arch;
///
/// Arch ECS 模块 - 核心适配器,桥接 Arch 到框架生命周期
///
-public sealed class ArchEcsModule : IServiceModule
+public sealed class ArchEcsModule : IArchEcsModule
{
- private readonly List> _systems = [];
+ private readonly ArchOptions _options;
private IIocContainer? _container;
private bool _isInitialized;
+ private IReadOnlyList> _systems = [];
private World? _world;
///
/// 构造函数
///
+ /// 配置选项
/// 是否启用模块
- public ArchEcsModule(bool enabled = true)
+ public ArchEcsModule(ArchOptions? options = null, bool enabled = true)
{
+ _options = options ?? new ArchOptions();
IsEnabled = enabled;
}
@@ -31,7 +33,7 @@ public sealed class ArchEcsModule : IServiceModule
///
/// 模块优先级
///
- public int Priority => 50;
+ public int Priority => _options.Priority;
///
/// 是否启用
@@ -47,8 +49,11 @@ public sealed class ArchEcsModule : IServiceModule
_container = container;
- // 创建并注册 World
- _world = World.Create();
+ // 注册模块自身
+ container.RegisterPlurality(this);
+
+ // 创建并注册 World(使用配置的容量)
+ _world = World.Create(_options.WorldCapacity);
container.Register(_world);
}
@@ -65,17 +70,13 @@ public sealed class ArchEcsModule : IServiceModule
return;
}
- // 从容器获取所有适配器
- var adapters = _container.GetAll>();
- if (adapters.Count > 0)
- {
- _systems.AddRange(adapters);
+ // 从容器按优先级获取所有适配器
+ _systems = _container.GetAllByPriority>();
- // 初始化所有系统(会调用 Arch 系统的 Initialize)
- foreach (var system in _systems)
- {
- system.Initialize();
- }
+ // 初始化所有系统(会调用 Arch 系统的 Initialize)
+ foreach (var system in _systems)
+ {
+ system.Initialize();
}
_isInitialized = true;
@@ -97,7 +98,7 @@ public sealed class ArchEcsModule : IServiceModule
system.Destroy();
}
- _systems.Clear();
+ _systems = [];
// 销毁 World
if (_world != null)
diff --git a/GFramework.Ecs.Arch/ArchOptions.cs b/GFramework.Ecs.Arch/ArchOptions.cs
new file mode 100644
index 0000000..adc17e4
--- /dev/null
+++ b/GFramework.Ecs.Arch/ArchOptions.cs
@@ -0,0 +1,22 @@
+namespace GFramework.Ecs.Arch;
+
+///
+/// Arch ECS 模块配置选项
+///
+public sealed class ArchOptions
+{
+ ///
+ /// World 初始容量(默认:1000)
+ ///
+ public int WorldCapacity { get; set; } = 1000;
+
+ ///
+ /// 是否启用统计信息(默认:false)
+ ///
+ public bool EnableStatistics { get; set; } = false;
+
+ ///
+ /// 模块优先级(默认:50)
+ ///
+ public int Priority { get; set; } = 50;
+}
\ No newline at end of file
diff --git a/GFramework.Core/ecs/ArchSystemAdapter.cs b/GFramework.Ecs.Arch/ArchSystemAdapter.cs
similarity index 96%
rename from GFramework.Core/ecs/ArchSystemAdapter.cs
rename to GFramework.Ecs.Arch/ArchSystemAdapter.cs
index 8a86c98..6f7e99f 100644
--- a/GFramework.Core/ecs/ArchSystemAdapter.cs
+++ b/GFramework.Ecs.Arch/ArchSystemAdapter.cs
@@ -3,19 +3,29 @@ using GFramework.Core.extensions;
using GFramework.Core.system;
using ArchSys = Arch.System;
-namespace GFramework.Core.ecs;
+namespace GFramework.Ecs.Arch;
///
/// Arch 系统适配器 - 桥接 Arch.System.ISystem<T> 到框架上下文
///
/// 系统数据类型(通常是 float 表示 deltaTime)
-public abstract class ArchSystemAdapter : AbstractSystem, ArchSys.ISystem
+public abstract class ArchSystemAdapter : AbstractSystem, IArchSystemAdapter, ArchSys.ISystem
{
///
/// 获取或设置 Arch ECS 世界的实例
///
public World World { get; private set; } = null!;
+ ///
+ /// 显式实现 Arch.System.ISystem<T> 的主更新方法
+ /// 调用受保护的虚方法 OnUpdate 以强制子类实现核心更新逻辑
+ ///
+ /// 系统数据参数(通常是 deltaTime)
+ public void Update(in T t)
+ {
+ OnUpdate(in t);
+ }
+
// ===== Arch 显式接口实现 =====
///
@@ -37,16 +47,6 @@ public abstract class ArchSystemAdapter : AbstractSystem, ArchSys.ISystem
OnBeforeUpdate(in t);
}
- ///
- /// 显式实现 Arch.System.ISystem<T> 的主更新方法
- /// 调用受保护的虚方法 OnUpdate 以强制子类实现核心更新逻辑
- ///
- /// 系统数据参数(通常是 deltaTime)
- public void Update(in T t)
- {
- OnUpdate(in t);
- }
-
///
/// 显式实现 Arch.System.ISystem<T> 的更新后回调方法
/// 调用受保护的虚方法 OnAfterUpdate 以允许子类自定义后处理逻辑
diff --git a/GFramework.Ecs.Arch/GFramework.Ecs.Arch.csproj b/GFramework.Ecs.Arch/GFramework.Ecs.Arch.csproj
new file mode 100644
index 0000000..2b58a0e
--- /dev/null
+++ b/GFramework.Ecs.Arch/GFramework.Ecs.Arch.csproj
@@ -0,0 +1,23 @@
+
+
+
+ GeWuYou.$(AssemblyName)
+ net8.0;net9.0;net10.0
+ disable
+ enable
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GFramework.Ecs.Arch/GlobalUsings.cs b/GFramework.Ecs.Arch/GlobalUsings.cs
new file mode 100644
index 0000000..50bd209
--- /dev/null
+++ b/GFramework.Ecs.Arch/GlobalUsings.cs
@@ -0,0 +1,5 @@
+global using System;
+global using System.Collections.Generic;
+global using System.Threading.Tasks;
+global using GFramework.Core.Abstractions;
+global using GFramework.Ecs.Arch.Abstractions;
\ No newline at end of file
diff --git a/GFramework.Ecs.Arch/README.md b/GFramework.Ecs.Arch/README.md
new file mode 100644
index 0000000..96501af
--- /dev/null
+++ b/GFramework.Ecs.Arch/README.md
@@ -0,0 +1,192 @@
+# GFramework.Ecs.Arch
+
+GFramework 的 Arch ECS 集成包,提供开箱即用的 ECS(Entity Component System)支持。
+
+## 特性
+
+- 🎯 **显式集成** - 符合 .NET 生态习惯的显式注册方式
+- 🔌 **零依赖** - 不使用时,Core 包无 Arch 依赖
+- 🎯 **类型安全** - 完整的类型系统和编译时检查
+- ⚡ **高性能** - 基于 Arch ECS 的高性能实现
+- 🔧 **易扩展** - 简单的系统适配器模式
+
+## 快速开始
+
+### 1. 安装包
+
+```bash
+dotnet add package GeWuYou.GFramework.Ecs.Arch
+```
+
+### 2. 注册 ECS 模块
+
+```csharp
+// 在架构初始化时添加 Arch ECS 支持
+var architecture = new GameArchitecture(config)
+ .UseArch(); // 添加 ECS 支持
+
+architecture.Initialize();
+```
+
+### 3. 带配置的注册
+
+```csharp
+var architecture = new GameArchitecture(config)
+ .UseArch(options =>
+ {
+ options.WorldCapacity = 2000;
+ options.EnableStatistics = true;
+ options.Priority = 50;
+ });
+
+architecture.Initialize();
+```
+
+```csharp
+using System.Runtime.InteropServices;
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Position(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Velocity(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+```
+
+### 5. 创建系统
+
+```csharp
+using Arch.Core;
+using GFramework.Ecs.Arch;
+
+public sealed class MovementSystem : ArchSystemAdapter
+{
+ private QueryDescription _query;
+
+ protected override void OnArchInitialize()
+ {
+ _query = new QueryDescription()
+ .WithAll();
+ }
+
+ protected override void OnUpdate(in float deltaTime)
+ {
+ World.Query(in _query, (ref Position pos, ref Velocity vel) =>
+ {
+ pos.X += vel.X * deltaTime;
+ pos.Y += vel.Y * deltaTime;
+ });
+ }
+}
+```
+
+### 6. 注册系统
+
+```csharp
+public class MyArchitecture : Architecture
+{
+ protected override void OnRegisterSystem(IIocContainer container)
+ {
+ container.Register();
+ }
+}
+```
+
+### 7. 创建实体
+
+```csharp
+var world = this.GetService();
+var entity = world.Create(
+ new Position(0, 0),
+ new Velocity(1, 1)
+);
+```
+
+### 8. 更新系统
+
+```csharp
+var ecsModule = this.GetService();
+ecsModule.Update(deltaTime);
+```
+
+## 配置选项
+
+### 代码配置
+
+```csharp
+var architecture = new GameArchitecture(config)
+ .UseArch(options =>
+ {
+ options.WorldCapacity = 2000;
+ options.EnableStatistics = true;
+ options.Priority = 50;
+ });
+```
+
+### 配置说明
+
+- `WorldCapacity` - World 初始容量(默认:1000)
+- `EnableStatistics` - 是否启用统计信息(默认:false)
+- `Priority` - 模块优先级(默认:50)
+
+## 架构说明
+
+### 显式注册模式
+
+本包采用 .NET 生态标准的显式注册模式,基于架构实例:
+
+**优点:**
+
+- ✅ 符合 .NET 生态习惯
+- ✅ 显式、可控
+- ✅ 易于测试和调试
+- ✅ 支持配置
+- ✅ 支持链式调用
+- ✅ 避免"魔法"行为
+
+**使用方式:**
+```csharp
+// 在架构初始化时添加
+var architecture = new GameArchitecture(config)
+ .UseArch(); // 显式注册
+
+architecture.Initialize();
+```
+
+详见:[INTEGRATION_PATTERN.md](INTEGRATION_PATTERN.md)
+
+### 系统适配器
+
+`ArchSystemAdapter` 桥接 Arch.System.ISystem 到 GFramework 架构:
+
+- 自动获取 World 实例
+- 集成到框架生命周期
+- 支持上下文感知(Context-Aware)
+
+### 生命周期
+
+1. **注册阶段** - 模块自动注册到架构
+2. **初始化阶段** - 创建 World,初始化系统
+3. **运行阶段** - 每帧调用 Update
+4. **销毁阶段** - 清理资源,销毁 World
+
+## 示例
+
+完整示例请参考 `GFramework.Ecs.Arch.Tests` 项目。
+
+## 依赖
+
+- GFramework.Core >= 1.0.0
+- Arch >= 2.1.0
+- Arch.System >= 1.1.0
+
+## 许可证
+
+MIT License
diff --git a/GFramework.Core/ecs/components/Position.cs b/GFramework.Ecs.Arch/components/Position.cs
similarity index 92%
rename from GFramework.Core/ecs/components/Position.cs
rename to GFramework.Ecs.Arch/components/Position.cs
index 204f66d..fe625d0 100644
--- a/GFramework.Core/ecs/components/Position.cs
+++ b/GFramework.Ecs.Arch/components/Position.cs
@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
-namespace GFramework.Core.ecs.components;
+namespace GFramework.Ecs.Arch.components;
///
/// 位置组件,用于表示实体在二维空间中的坐标位置。
diff --git a/GFramework.Core/ecs/components/Velocity.cs b/GFramework.Ecs.Arch/components/Velocity.cs
similarity index 93%
rename from GFramework.Core/ecs/components/Velocity.cs
rename to GFramework.Ecs.Arch/components/Velocity.cs
index 26465b2..dab5eb6 100644
--- a/GFramework.Core/ecs/components/Velocity.cs
+++ b/GFramework.Ecs.Arch/components/Velocity.cs
@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
-namespace GFramework.Core.ecs.components;
+namespace GFramework.Ecs.Arch.components;
///
/// 速度结构体,用于表示二维空间中实体的瞬时速度向量
diff --git a/GFramework.Ecs.Arch/extensions/ArchExtensions.cs b/GFramework.Ecs.Arch/extensions/ArchExtensions.cs
new file mode 100644
index 0000000..dda51b1
--- /dev/null
+++ b/GFramework.Ecs.Arch/extensions/ArchExtensions.cs
@@ -0,0 +1,31 @@
+using GFramework.Core.Abstractions.architecture;
+
+namespace GFramework.Ecs.Arch.extensions;
+
+///
+/// Arch ECS 扩展方法
+///
+public static class ArchExtensions
+{
+ ///
+ /// 添加 Arch ECS 支持到架构中
+ ///
+ /// 架构类型
+ /// 架构实例
+ /// 可选的配置委托
+ /// 架构实例,支持链式调用
+ public static TArchitecture UseArch(
+ this TArchitecture architecture,
+ Action? configure = null)
+ where TArchitecture : IArchitecture
+ {
+ // 配置选项
+ var options = new ArchOptions();
+ configure?.Invoke(options);
+
+ // 注册模块(传递配置选项)
+ ArchitectureModuleRegistry.Register(() => new ArchEcsModule(options, enabled: true));
+
+ return architecture;
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Core/ecs/systems/MovementSystem.cs b/GFramework.Ecs.Arch/systems/MovementSystem.cs
similarity index 92%
rename from GFramework.Core/ecs/systems/MovementSystem.cs
rename to GFramework.Ecs.Arch/systems/MovementSystem.cs
index 897ca8b..3f3b923 100644
--- a/GFramework.Core/ecs/systems/MovementSystem.cs
+++ b/GFramework.Ecs.Arch/systems/MovementSystem.cs
@@ -1,7 +1,7 @@
using Arch.Core;
-using GFramework.Core.ecs.components;
+using GFramework.Ecs.Arch.components;
-namespace GFramework.Core.ecs.systems;
+namespace GFramework.Ecs.Arch.systems;
///
/// 移动系统 - 继承 ArchSystemAdapter
diff --git a/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj b/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj
index 3a8c827..4941dcf 100644
--- a/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj
+++ b/GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj
@@ -1,9 +1,11 @@
+ net8.0;net10.0
disable
enable
- net10.0;net8.0
+ false
+ true
diff --git a/GFramework.csproj b/GFramework.csproj
index 09f1d65..ae91b88 100644
--- a/GFramework.csproj
+++ b/GFramework.csproj
@@ -47,6 +47,9 @@
+
+
+
@@ -82,6 +85,9 @@
+
+
+
@@ -103,6 +109,9 @@
+
+
+
diff --git a/GFramework.sln b/GFramework.sln
index 3eba55b..04b1d8f 100644
--- a/GFramework.sln
+++ b/GFramework.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework ", "GFramework.csproj", "{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework", "GFramework.csproj", "{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.SourceGenerators", "GFramework.SourceGenerators\GFramework.SourceGenerators.csproj", "{E9D51809-0351-4B83-B85B-B5F469AAB3B8}"
EndProject
@@ -26,63 +26,216 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Game.Abstraction
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Core.Tests", "GFramework.Core.Tests\GFramework.Core.Tests.csproj", "{759BCD95-A9D9-4D8F-9255-A9F1B661DF74}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Ecs.Arch.Abstractions", "GFramework.Ecs.Arch.Abstractions\GFramework.Ecs.Arch.Abstractions.csproj", "{5E1488B2-6554-408D-83FB-EB2FFFABF545}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Ecs.Arch", "GFramework.Ecs.Arch\GFramework.Ecs.Arch.csproj", "{E9B49EE9-25BC-47C1-83CE-92F636B9D491}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GFramework.Ecs.Arch.Tests", "GFramework.Ecs.Arch.Tests\GFramework.Ecs.Arch.Tests.csproj", "{112CF413-4596-4AA3-B3FE-65532802FDD6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Debug|x64.Build.0 = Debug|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Debug|x86.Build.0 = Debug|Any CPU
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x64.ActiveCfg = Release|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x64.Build.0 = Release|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x86.ActiveCfg = Release|Any CPU
+ {9BEDDD6C-DF8B-4E71-9C75-F44EC669ABBD}.Release|x86.Build.0 = Release|Any CPU
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x64.Build.0 = Debug|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Debug|x86.Build.0 = Debug|Any CPU
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x64.ActiveCfg = Release|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x64.Build.0 = Release|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x86.ActiveCfg = Release|Any CPU
+ {E9D51809-0351-4B83-B85B-B5F469AAB3B8}.Release|x86.Build.0 = Release|Any CPU
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x64.Build.0 = Debug|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Debug|x86.Build.0 = Debug|Any CPU
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x64.ActiveCfg = Release|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x64.Build.0 = Release|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x86.ActiveCfg = Release|Any CPU
+ {84C5C3C9-5620-4924-BA04-92F813F2B70F}.Release|x86.Build.0 = Release|Any CPU
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|x64.Build.0 = Debug|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Debug|x86.Build.0 = Debug|Any CPU
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Release|x64.ActiveCfg = Release|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Release|x64.Build.0 = Release|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Release|x86.ActiveCfg = Release|Any CPU
+ {A6D5854D-79EA-487A-9ED9-396E6A1F8031}.Release|x86.Build.0 = Release|Any CPU
{FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Debug|x64.Build.0 = Debug|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Debug|x86.Build.0 = Debug|Any CPU
{FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Release|x64.ActiveCfg = Release|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Release|x64.Build.0 = Release|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Release|x86.ActiveCfg = Release|Any CPU
+ {FC56D81A-3A3B-4B49-B318-363DFA0D8206}.Release|x86.Build.0 = Release|Any CPU
{0B00816B-E8B2-4562-8C11-0C06CE761638}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B00816B-E8B2-4562-8C11-0C06CE761638}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Debug|x64.Build.0 = Debug|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Debug|x86.Build.0 = Debug|Any CPU
{0B00816B-E8B2-4562-8C11-0C06CE761638}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B00816B-E8B2-4562-8C11-0C06CE761638}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Release|x64.ActiveCfg = Release|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Release|x64.Build.0 = Release|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Release|x86.ActiveCfg = Release|Any CPU
+ {0B00816B-E8B2-4562-8C11-0C06CE761638}.Release|x86.Build.0 = Release|Any CPU
{C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Debug|x64.Build.0 = Debug|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Debug|x86.Build.0 = Debug|Any CPU
{C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Release|x64.ActiveCfg = Release|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Release|x64.Build.0 = Release|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Release|x86.ActiveCfg = Release|Any CPU
+ {C56FD287-CBC6-4C44-B3DF-103FA3660CA0}.Release|x86.Build.0 = Release|Any CPU
{3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Debug|x64.Build.0 = Debug|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Debug|x86.Build.0 = Debug|Any CPU
{3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Release|x64.ActiveCfg = Release|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Release|x64.Build.0 = Release|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Release|x86.ActiveCfg = Release|Any CPU
+ {3A1132B7-EC3B-4BB6-A752-8ADC92BC08A0}.Release|x86.Build.0 = Release|Any CPU
{BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Debug|x64.Build.0 = Debug|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Debug|x86.Build.0 = Debug|Any CPU
{BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Release|x64.ActiveCfg = Release|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Release|x64.Build.0 = Release|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Release|x86.ActiveCfg = Release|Any CPU
+ {BB047F43-6AA0-4EA0-8AE9-E6B9784D9E8E}.Release|x86.Build.0 = Release|Any CPU
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|x64.Build.0 = Debug|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Debug|x86.Build.0 = Debug|Any CPU
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|x64.ActiveCfg = Release|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|x64.Build.0 = Release|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|x86.ActiveCfg = Release|Any CPU
+ {B6511C9A-40E1-4E51-8D1F-18EAFB3C5BFC}.Release|x86.Build.0 = Release|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|x64.Build.0 = Debug|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Debug|x86.Build.0 = Debug|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|x64.ActiveCfg = Release|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|x64.Build.0 = Release|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|x86.ActiveCfg = Release|Any CPU
+ {31BA9F62-153A-4943-A8A0-7571FC7D5FEE}.Release|x86.Build.0 = Release|Any CPU
{E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Debug|x64.Build.0 = Debug|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Debug|x86.Build.0 = Debug|Any CPU
{E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Release|x64.ActiveCfg = Release|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Release|x64.Build.0 = Release|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Release|x86.ActiveCfg = Release|Any CPU
+ {E20DBA4C-CEB9-4184-B614-5A99A9AE4472}.Release|x86.Build.0 = Release|Any CPU
{759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Debug|x64.Build.0 = Debug|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Debug|x86.Build.0 = Debug|Any CPU
{759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Release|Any CPU.Build.0 = Release|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Release|x64.ActiveCfg = Release|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Release|x64.Build.0 = Release|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Release|x86.ActiveCfg = Release|Any CPU
+ {759BCD95-A9D9-4D8F-9255-A9F1B661DF74}.Release|x86.Build.0 = Release|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Debug|x64.Build.0 = Debug|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Debug|x86.Build.0 = Debug|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Release|x64.ActiveCfg = Release|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Release|x64.Build.0 = Release|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Release|x86.ActiveCfg = Release|Any CPU
+ {5E1488B2-6554-408D-83FB-EB2FFFABF545}.Release|x86.Build.0 = Release|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Debug|x64.Build.0 = Debug|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Debug|x86.Build.0 = Debug|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Release|x64.ActiveCfg = Release|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Release|x64.Build.0 = Release|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Release|x86.ActiveCfg = Release|Any CPU
+ {E9B49EE9-25BC-47C1-83CE-92F636B9D491}.Release|x86.Build.0 = Release|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Debug|x64.Build.0 = Debug|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Debug|x86.Build.0 = Debug|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Release|x64.ActiveCfg = Release|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Release|x64.Build.0 = Release|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Release|x86.ActiveCfg = Release|Any CPU
+ {112CF413-4596-4AA3-B3FE-65532802FDD6}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index a6aaef0..cc889fe 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -47,6 +47,7 @@ export default defineConfig({
{ text: '首页', link: '/zh-CN/' },
{ text: '入门指南', link: '/zh-CN/getting-started' },
{ text: 'Core', link: '/zh-CN/core/' },
+ { text: 'ECS', link: '/zh-CN/ecs/' },
{ text: 'Game', link: '/zh-CN/game/' },
{ text: 'Godot', link: '/zh-CN/godot/' },
{ text: '源码生成器', link: '/zh-CN/source-generators' },
@@ -91,7 +92,6 @@ export default defineConfig({
{ text: '事件系统', link: '/zh-CN/core/events' },
{ text: '属性系统', link: '/zh-CN/core/property' },
{ text: 'IoC容器', link: '/zh-CN/core/ioc' },
- { text: 'ECS 系统集成', link: '/zh-CN/core/ecs' },
{ text: '协程系统', link: '/zh-CN/core/coroutine' },
{ text: '状态机', link: '/zh-CN/core/state-machine' },
{ text: '暂停系统', link: '/zh-CN/core/pause' },
@@ -110,6 +110,16 @@ export default defineConfig({
}
],
+ '/zh-CN/ecs/': [
+ {
+ text: 'ECS 系统集成',
+ items: [
+ { text: 'ECS 概述', link: '/zh-CN/ecs/' },
+ { text: 'Arch ECS 集成', link: '/zh-CN/ecs/arch' }
+ ]
+ }
+ ],
+
'/zh-CN/game/': [
{
text: 'Game 游戏模块',
diff --git a/docs/zh-CN/core/ecs.md b/docs/zh-CN/core/ecs.md
deleted file mode 100644
index 527fa6a..0000000
--- a/docs/zh-CN/core/ecs.md
+++ /dev/null
@@ -1,1006 +0,0 @@
----
-title: ECS 系统集成
-description: ECS(Entity Component System)系统集成指南,基于 Arch.Core 实现高性能的实体组件系统。
----
-
-# ECS 系统集成
-
-## 概述
-
-GFramework 集成了 [Arch.Core](https://github.com/genaray/Arch) ECS 框架,提供高性能的实体组件系统(Entity Component
-System)架构。通过 ECS 模式,你可以构建数据驱动、高度可扩展的游戏系统。
-
-**主要特性**:
-
-- 基于 Arch.Core 的高性能 ECS 实现
-- 与 GFramework 架构无缝集成
-- 支持组件查询和批量处理
-- 零 GC 分配的组件访问
-- 灵活的系统生命周期管理
-- 支持多线程并行处理(Arch 原生支持)
-
-**性能特点**:
-
-- 10,000 个实体更新 < 100ms
-- 1,000 个实体创建 < 50ms
-- 基于 Archetype 的高效内存布局
-- 支持 SIMD 优化
-
-## 核心概念
-
-### Entity(实体)
-
-实体是游戏世界中的基本对象,本质上是一个唯一标识符(ID)。实体本身不包含数据或逻辑,只是组件的容器。
-
-```csharp
-using Arch.Core;
-
-// 创建实体
-var entity = world.Create();
-
-// 创建带组件的实体
-var entity = world.Create(new Position(0, 0), new Velocity(1, 1));
-```
-
-### Component(组件)
-
-组件是纯数据结构,用于存储实体的状态。组件应该是简单的值类型(struct),不包含逻辑。
-
-```csharp
-using System.Runtime.InteropServices;
-
-///
-/// 位置组件
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct Position(float x, float y)
-{
- public float X { get; set; } = x;
- public float Y { get; set; } = y;
-}
-
-///
-/// 速度组件
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct Velocity(float x, float y)
-{
- public float X { get; set; } = x;
- public float Y { get; set; } = y;
-}
-```
-
-**组件设计原则**:
-
-- 使用 `struct` 而不是 `class`
-- 只包含数据,不包含逻辑
-- 使用 `[StructLayout(LayoutKind.Sequential)]` 优化内存布局
-- 保持组件小而专注
-
-### System(系统)
-
-系统包含游戏逻辑,负责处理具有特定组件组合的实体。在 GFramework 中,系统通过继承 `ArchSystemAdapter<T>` 来实现。
-
-```csharp
-using Arch.Core;
-using GFramework.Core.ecs;
-
-///
-/// 移动系统 - 更新实体位置
-///
-public sealed class MovementSystem : ArchSystemAdapter
-{
- private QueryDescription _query;
-
- protected override void OnArchInitialize()
- {
- // 创建查询:查找所有同时拥有 Position 和 Velocity 组件的实体
- _query = new QueryDescription()
- .WithAll();
- }
-
- protected override void OnUpdate(in float deltaTime)
- {
- // 查询并更新所有符合条件的实体
- World.Query(in _query, (ref Position pos, ref Velocity vel) =>
- {
- pos.X += vel.X * deltaTime;
- pos.Y += vel.Y * deltaTime;
- });
- }
-}
-```
-
-### World(世界)
-
-World 是 ECS 的核心容器,管理所有实体和组件。GFramework 通过 `ArchEcsModule` 自动创建和管理 World。
-
-```csharp
-// World 由 ArchEcsModule 自动创建和注册到 IoC 容器
-// 在系统中可以直接访问
-public class MySystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // 访问 World
- var entityCount = World.Size;
- }
-}
-```
-
-### Arch.Core 集成
-
-GFramework 通过以下组件桥接 Arch.Core 到框架生命周期:
-
-- **ArchEcsModule**:ECS 模块,管理 World 和系统生命周期
-- **ArchSystemAdapter<T>**:系统适配器,桥接 Arch 系统到 GFramework
-
-## 基本用法
-
-### 1. 定义组件
-
-```csharp
-using System.Runtime.InteropServices;
-
-namespace MyGame.Components;
-
-[StructLayout(LayoutKind.Sequential)]
-public struct Health(float current, float max)
-{
- public float Current { get; set; } = current;
- public float Max { get; set; } = max;
-}
-
-[StructLayout(LayoutKind.Sequential)]
-public struct Damage(float value)
-{
- public float Value { get; set; } = value;
-}
-
-[StructLayout(LayoutKind.Sequential)]
-public struct PlayerTag
-{
- // 标签组件,不需要数据
-}
-```
-
-### 2. 创建系统
-
-```csharp
-using Arch.Core;
-using GFramework.Core.ecs;
-using MyGame.Components;
-
-namespace MyGame.Systems;
-
-///
-/// 伤害系统 - 处理伤害逻辑
-///
-public sealed class DamageSystem : ArchSystemAdapter
-{
- private QueryDescription _query;
-
- protected override void OnArchInitialize()
- {
- // 查询所有具有 Health 和 Damage 组件的实体
- _query = new QueryDescription()
- .WithAll();
- }
-
- protected override void OnUpdate(in float deltaTime)
- {
- // 处理伤害
- World.Query(in _query, (Entity entity, ref Health health, ref Damage damage) =>
- {
- health.Current -= damage.Value * deltaTime;
-
- // 如果生命值耗尽,移除伤害组件
- if (health.Current <= 0)
- {
- health.Current = 0;
- World.Remove(entity);
- }
- });
- }
-}
-```
-
-### 3. 注册 ECS 模块
-
-```csharp
-using GFramework.Core.architecture;
-using GFramework.Core.ecs;
-using MyGame.Systems;
-
-public class GameArchitecture : Architecture
-{
- protected override void Init()
- {
- // 注册 ECS 系统
- RegisterSystem(new MovementSystem());
- RegisterSystem(new DamageSystem());
-
- // 安装 ECS 模块
- InstallModule(new ArchEcsModule(enabled: true));
- }
-}
-```
-
-### 4. 创建和管理实体
-
-```csharp
-using Arch.Core;
-using GFramework.Core.Abstractions.controller;
-using MyGame.Components;
-using GFramework.Core.Abstractions.controller;
-using GFramework.SourceGenerators.Abstractions.rule;
-
-[ContextAware]
-public partial class GameController : IController
-{
- private World _world;
-
- public void Start()
- {
- // 获取 World
- _world = this.GetService();
-
- // 创建玩家实体
- var player = _world.Create(
- new Position(0, 0),
- new Velocity(0, 0),
- new Health(100, 100),
- new PlayerTag()
- );
-
- // 创建敌人实体
- var enemy = _world.Create(
- new Position(10, 10),
- new Velocity(-1, 0),
- new Health(50, 50)
- );
- }
-
- public void ApplyDamage(Entity entity, float damageValue)
- {
- // 添加伤害组件
- if (_world.Has(entity))
- {
- _world.Add(entity, new Damage(damageValue));
- }
- }
-}
-```
-
-### 5. 更新 ECS 系统
-
-```csharp
-// 在游戏主循环中更新 ECS
-public class GameLoop
-{
- private ArchEcsModule _ecsModule;
-
- public void Update(float deltaTime)
- {
- // 更新所有 ECS 系统
- _ecsModule.Update(deltaTime);
- }
-}
-```
-
-## 高级用法
-
-### 查询实体
-
-Arch 提供了强大的查询 API,支持多种过滤条件:
-
-```csharp
-using Arch.Core;
-
-public class QueryExampleSystem : ArchSystemAdapter
-{
- private QueryDescription _query1;
- private QueryDescription _query2;
- private QueryDescription _query3;
-
- protected override void OnArchInitialize()
- {
- // 查询:必须有 Position 和 Velocity
- _query1 = new QueryDescription()
- .WithAll();
-
- // 查询:必须有 Health,但不能有 Damage
- _query2 = new QueryDescription()
- .WithAll()
- .WithNone();
-
- // 查询:必须有 Position,可选 Velocity
- _query3 = new QueryDescription()
- .WithAll()
- .WithAny();
- }
-
- protected override void OnUpdate(in float deltaTime)
- {
- // 使用查询 1
- World.Query(in _query1, (ref Position pos, ref Velocity vel) =>
- {
- // 处理逻辑
- });
-
- // 使用查询 2
- World.Query(in _query2, (Entity entity, ref Health health) =>
- {
- // 处理逻辑
- });
- }
-}
-```
-
-### 系统生命周期钩子
-
-`ArchSystemAdapter<T>` 提供了多个生命周期钩子:
-
-```csharp
-public class LifecycleExampleSystem : ArchSystemAdapter
-{
- protected override void OnArchInitialize()
- {
- // Arch 系统初始化
- // 在这里创建查询、初始化资源
- }
-
- protected override void OnBeforeUpdate(in float deltaTime)
- {
- // 更新前调用
- // 可用于预处理逻辑
- }
-
- protected override void OnUpdate(in float deltaTime)
- {
- // 主更新逻辑
- }
-
- protected override void OnAfterUpdate(in float deltaTime)
- {
- // 更新后调用
- // 可用于后处理逻辑
- }
-
- protected override void OnArchDispose()
- {
- // 资源清理
- }
-}
-```
-
-### 组件操作
-
-```csharp
-using Arch.Core;
-
-public class ComponentOperations
-{
- private World _world;
-
- public void Examples()
- {
- var entity = _world.Create();
-
- // 添加组件
- _world.Add(entity, new Position(0, 0));
- _world.Add(entity, new Velocity(1, 1));
-
- // 检查组件
- if (_world.Has(entity))
- {
- // 获取组件引用(零 GC 分配)
- ref var pos = ref _world.Get(entity);
- pos.X += 10;
- }
-
- // 设置组件(替换现有值)
- _world.Set(entity, new Position(100, 100));
-
- // 移除组件
- _world.Remove(entity);
-
- // 销毁实体
- _world.Destroy(entity);
- }
-}
-```
-
-### 批量操作
-
-```csharp
-public class BatchOperations
-{
- private World _world;
-
- public void CreateMultipleEntities()
- {
- // 批量创建实体
- for (int i = 0; i < 1000; i++)
- {
- _world.Create(
- new Position(i, i),
- new Velocity(1, 1)
- );
- }
- }
-
- public void ClearAllEntities()
- {
- // 清空所有实体
- _world.Clear();
- }
-}
-```
-
-### 实体查询和迭代
-
-```csharp
-public class EntityIterationSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // 方式 1:使用查询和 Lambda
- var query = new QueryDescription().WithAll();
- World.Query(in query, (ref Position pos) =>
- {
- // 处理每个实体
- });
-
- // 方式 2:获取实体引用
- World.Query(in query, (Entity entity, ref Position pos) =>
- {
- // 可以访问实体 ID
- if (pos.X > 100)
- {
- World.Destroy(entity);
- }
- });
-
- // 方式 3:多组件查询
- var multiQuery = new QueryDescription()
- .WithAll();
-
- World.Query(in multiQuery, (
- Entity entity,
- ref Position pos,
- ref Velocity vel,
- ref Health health) =>
- {
- // 处理多个组件
- });
- }
-}
-```
-
-## 性能优化
-
-### 1. 使用 struct 组件
-
-```csharp
-// ✅ 推荐:使用 struct
-[StructLayout(LayoutKind.Sequential)]
-public struct Position(float x, float y)
-{
- public float X { get; set; } = x;
- public float Y { get; set; } = y;
-}
-
-// ❌ 不推荐:使用 class
-public class Position
-{
- public float X { get; set; }
- public float Y { get; set; }
-}
-```
-
-### 2. 缓存查询
-
-```csharp
-public class OptimizedSystem : ArchSystemAdapter
-{
- // ✅ 推荐:缓存查询
- private QueryDescription _cachedQuery;
-
- protected override void OnArchInitialize()
- {
- _cachedQuery = new QueryDescription()
- .WithAll();
- }
-
- protected override void OnUpdate(in float deltaTime)
- {
- // 使用缓存的查询
- World.Query(in _cachedQuery, (ref Position pos, ref Velocity vel) =>
- {
- pos.X += vel.X * deltaTime;
- pos.Y += vel.Y * deltaTime;
- });
- }
-}
-
-// ❌ 不推荐:每次创建新查询
-public class UnoptimizedSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // 每帧创建新查询(性能差)
- var query = new QueryDescription().WithAll();
- World.Query(in query, (ref Position pos, ref Velocity vel) =>
- {
- // ...
- });
- }
-}
-```
-
-### 3. 使用 ref 访问组件
-
-```csharp
-// ✅ 推荐:使用 ref 避免复制
-World.Query(in query, (ref Position pos, ref Velocity vel) =>
-{
- pos.X += vel.X; // 直接修改,零 GC
-});
-
-// ❌ 不推荐:不使用 ref
-World.Query(in query, (Position pos, Velocity vel) =>
-{
- pos.X += vel.X; // 复制值,修改不会生效
-});
-```
-
-### 4. 组件大小优化
-
-```csharp
-// ✅ 推荐:小而专注的组件
-public struct Position(float x, float y)
-{
- public float X { get; set; } = x;
- public float Y { get; set; } = y;
-}
-
-public struct Velocity(float x, float y)
-{
- public float X { get; set; } = x;
- public float Y { get; set; } = y;
-}
-
-// ❌ 不推荐:大而全的组件
-public struct Transform
-{
- public float X, Y, Z;
- public float RotationX, RotationY, RotationZ;
- public float ScaleX, ScaleY, ScaleZ;
- public float VelocityX, VelocityY, VelocityZ;
- // ... 太多数据
-}
-```
-
-### 5. 批量处理
-
-```csharp
-public class BatchProcessingSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // ✅ 推荐:批量处理
- var query = new QueryDescription().WithAll();
- World.Query(in query, (ref Position pos, ref Velocity vel) =>
- {
- // 一次查询处理所有实体
- pos.X += vel.X * deltaTime;
- pos.Y += vel.Y * deltaTime;
- });
- }
-}
-
-// ❌ 不推荐:逐个处理
-public class IndividualProcessingSystem : ArchSystemAdapter
-{
- private List _entities = new();
-
- protected override void OnUpdate(in float deltaTime)
- {
- foreach (var entity in _entities)
- {
- ref var pos = ref World.Get(entity);
- ref var vel = ref World.Get(entity);
- pos.X += vel.X * deltaTime;
- pos.Y += vel.Y * deltaTime;
- }
- }
-}
-```
-
-## 最佳实践
-
-### 1. ECS 设计模式
-
-**组件组合优于继承**:
-
-```csharp
-// ✅ 推荐:使用组件组合
-var player = world.Create(
- new Position(0, 0),
- new Velocity(0, 0),
- new Health(100, 100),
- new PlayerTag(),
- new Controllable()
-);
-
-var enemy = world.Create(
- new Position(10, 10),
- new Velocity(-1, 0),
- new Health(50, 50),
- new EnemyTag(),
- new AI()
-);
-
-// ❌ 不推荐:使用继承
-public class Player : Entity { }
-public class Enemy : Entity { }
-```
-
-**单一职责系统**:
-
-```csharp
-// ✅ 推荐:每个系统只负责一件事
-public class MovementSystem : ArchSystemAdapter
-{
- // 只负责移动
-}
-
-public class CollisionSystem : ArchSystemAdapter
-{
- // 只负责碰撞检测
-}
-
-public class DamageSystem : ArchSystemAdapter
-{
- // 只负责伤害处理
-}
-
-// ❌ 不推荐:一个系统做太多事
-public class GameplaySystem : ArchSystemAdapter
-{
- // 移动、碰撞、伤害、AI... 太多职责
-}
-```
-
-### 2. 与传统架构结合
-
-ECS 可以与 GFramework 的传统架构(Model、System、Utility)结合使用:
-
-```csharp
-// Model 存储全局状态
-public class GameStateModel : AbstractModel
-{
- public int Score { get; set; }
- public int Level { get; set; }
-}
-
-// ECS System 处理实体逻辑
-public class EnemySpawnSystem : ArchSystemAdapter
-{
- private float _spawnTimer;
-
- protected override void OnUpdate(in float deltaTime)
- {
- _spawnTimer += deltaTime;
-
- if (_spawnTimer >= 2.0f)
- {
- // 获取 Model
- var gameState = this.GetModel();
-
- // 根据关卡生成敌人
- var enemyCount = gameState.Level * 2;
- for (int i = 0; i < enemyCount; i++)
- {
- World.Create(
- new Position(Random.Shared.Next(0, 100), 0),
- new Velocity(0, -1),
- new Health(50, 50),
- new EnemyTag()
- );
- }
-
- _spawnTimer = 0;
- }
- }
-}
-
-// 传统 System 处理游戏逻辑
-public class ScoreSystem : AbstractSystem
-{
- protected override void OnInit()
- {
- // 监听敌人死亡事件
- this.RegisterEvent(OnEnemyDestroyed);
- }
-
- private void OnEnemyDestroyed(EnemyDestroyedEvent e)
- {
- var gameState = this.GetModel();
- gameState.Score += 100;
- }
-}
-```
-
-### 3. 事件集成
-
-ECS 系统可以发送和接收框架事件:
-
-```csharp
-// 定义事件
-public struct EnemyDestroyedEvent
-{
- public Entity Enemy { get; init; }
- public int Score { get; init; }
-}
-
-// ECS 系统发送事件
-public class HealthSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- var query = new QueryDescription()
- .WithAll();
-
- World.Query(in query, (Entity entity, ref Health health) =>
- {
- if (health.Current <= 0)
- {
- // 发送事件
- this.SendEvent(new EnemyDestroyedEvent
- {
- Enemy = entity,
- Score = 100
- });
-
- // 销毁实体
- World.Destroy(entity);
- }
- });
- }
-}
-
-// 传统系统接收事件
-public class UISystem : AbstractSystem
-{
- protected override void OnInit()
- {
- this.RegisterEvent(OnEnemyDestroyed);
- }
-
- private void OnEnemyDestroyed(EnemyDestroyedEvent e)
- {
- // 更新 UI
- Console.WriteLine($"Enemy destroyed! +{e.Score} points");
- }
-}
-```
-
-### 4. 标签组件
-
-使用空结构体作为标签来分类实体:
-
-```csharp
-// 定义标签组件
-public struct PlayerTag { }
-public struct EnemyTag { }
-public struct BulletTag { }
-public struct DeadTag { }
-
-// 使用标签过滤实体
-public class PlayerMovementSystem : ArchSystemAdapter
-{
- private QueryDescription _query;
-
- protected override void OnArchInitialize()
- {
- // 只处理玩家实体
- _query = new QueryDescription()
- .WithAll()
- .WithNone();
- }
-
- protected override void OnUpdate(in float deltaTime)
- {
- World.Query(in _query, (ref Position pos, ref Velocity vel) =>
- {
- // 只更新活着的玩家
- pos.X += vel.X * deltaTime;
- pos.Y += vel.Y * deltaTime;
- });
- }
-}
-```
-
-### 5. 组件生命周期管理
-
-```csharp
-public class LifecycleManagementSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // 处理临时效果
- var buffQuery = new QueryDescription().WithAll();
- World.Query(in buffQuery, (Entity entity, ref BuffComponent buff) =>
- {
- buff.Duration -= deltaTime;
-
- if (buff.Duration <= 0)
- {
- // 移除过期的 Buff
- World.Remove(entity);
- }
- });
-
- // 清理死亡实体
- var deadQuery = new QueryDescription().WithAll();
- World.Query(in deadQuery, (Entity entity) =>
- {
- World.Destroy(entity);
- });
- }
-}
-```
-
-## 常见问题
-
-### Q: 如何在 ECS 系统中访问其他服务?
-
-A: `ArchSystemAdapter<T>` 继承自 `AbstractSystem`,可以使用所有 GFramework 的扩展方法:
-
-```csharp
-public class ServiceAccessSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // 获取 Model
- var playerModel = this.GetModel();
-
- // 获取 Utility
- var timeUtility = this.GetUtility();
-
- // 发送命令
- this.SendCommand(new SaveGameCommand());
-
- // 发送查询
- var score = this.SendQuery(new GetScoreQuery());
-
- // 发送事件
- this.SendEvent(new GameOverEvent());
- }
-}
-```
-
-### Q: ECS 和传统架构如何选择?
-
-A: 根据场景选择:
-
-- **使用 ECS**:大量相似实体、需要高性能批量处理(敌人、子弹、粒子)
-- **使用传统架构**:全局状态、单例服务、UI 逻辑、游戏流程控制
-
-### Q: 如何调试 ECS 系统?
-
-A: 使用以下方法:
-
-```csharp
-public class DebugSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- // 打印实体数量
- Console.WriteLine($"Total entities: {World.Size}");
-
- // 查询特定实体
- var query = new QueryDescription().WithAll();
- var count = 0;
- World.Query(in query, (Entity entity, ref Position pos) =>
- {
- count++;
- Console.WriteLine($"Entity {entity.Id}: ({pos.X}, {pos.Y})");
- });
-
- Console.WriteLine($"Entities with Position: {count}");
- }
-}
-```
-
-### Q: 如何处理实体之间的交互?
-
-A: 使用查询和事件:
-
-```csharp
-public class CollisionSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- var playerQuery = new QueryDescription()
- .WithAll();
- var enemyQuery = new QueryDescription()
- .WithAll();
-
- // 检测玩家和敌人的碰撞
- World.Query(in playerQuery, (Entity player, ref Position playerPos) =>
- {
- World.Query(in enemyQuery, (Entity enemy, ref Position enemyPos) =>
- {
- var distance = Math.Sqrt(
- Math.Pow(playerPos.X - enemyPos.X, 2) +
- Math.Pow(playerPos.Y - enemyPos.Y, 2)
- );
-
- if (distance < 1.0f)
- {
- // 发送碰撞事件
- this.SendEvent(new CollisionEvent
- {
- Entity1 = player,
- Entity2 = enemy
- });
- }
- });
- });
- }
-}
-```
-
-### Q: 如何优化大量实体的性能?
-
-A: 参考性能优化章节,主要策略:
-
-1. 使用 struct 组件
-2. 缓存查询
-3. 使用 ref 访问组件
-4. 批量处理
-5. 合理设计组件大小
-6. 使用 Arch 的并行查询(高级特性)
-
-### Q: 可以在运行时动态添加/移除组件吗?
-
-A: 可以,Arch 支持运行时修改实体的组件:
-
-```csharp
-public class DynamicComponentSystem : ArchSystemAdapter
-{
- protected override void OnUpdate(in float deltaTime)
- {
- var query = new QueryDescription().WithAll();
-
- World.Query(in query, (Entity entity, ref Position pos) =>
- {
- // 动态添加组件
- if (pos.X > 100 && !World.Has(entity))
- {
- World.Add(entity, new FastTag());
- }
-
- // 动态移除组件
- if (pos.X < 0 && World.Has(entity))
- {
- World.Remove(entity);
- }
- });
- }
-}
-```
-
-## 相关资源
-
-- [Arch.Core 官方文档](https://github.com/genaray/Arch)
-- [Architecture 包使用说明](./architecture.md)
-- [System 包使用说明](./system.md)
-- [事件系统](./events.md)
-
----
-
-**许可证**:Apache 2.0
diff --git a/docs/zh-CN/ecs/arch.md b/docs/zh-CN/ecs/arch.md
new file mode 100644
index 0000000..19a1441
--- /dev/null
+++ b/docs/zh-CN/ecs/arch.md
@@ -0,0 +1,751 @@
+---
+title: Arch ECS 集成
+description: GFramework 的 Arch ECS 集成包使用指南,提供高性能的实体组件系统支持。
+---
+
+# Arch ECS 集成
+
+## 概述
+
+`GFramework.Ecs.Arch` 是 GFramework 的 Arch ECS 集成包,提供开箱即用的 ECS(Entity Component
+System)支持。基于 [Arch.Core](https://github.com/genaray/Arch) 实现,具有极致的性能和简洁的 API。
+
+**主要特性**:
+
+- 🎯 **显式集成** - 符合 .NET 生态习惯的显式注册方式
+- 🔌 **零依赖** - 不使用时,Core 包无 Arch 依赖
+- 🎯 **类型安全** - 完整的类型系统和编译时检查
+- ⚡ **高性能** - 基于 Arch ECS 的高性能实现
+- 🔧 **易扩展** - 简单的系统适配器模式
+- 📊 **优先级支持** - 系统按优先级顺序执行
+
+**性能特点**:
+
+- 10,000 个实体更新 < 100ms
+- 1,000 个实体创建 < 50ms
+- 基于 Archetype 的高效内存布局
+- 零 GC 分配的组件访问
+
+## 安装
+
+```bash
+dotnet add package GeWuYou.GFramework.Ecs.Arch
+```
+
+## 快速开始
+
+### 1. 注册 ECS 模块
+
+```csharp
+using GFramework.Core.architecture;
+using GFramework.Ecs.Arch.extensions;
+
+public class GameArchitecture : Architecture
+{
+ public GameArchitecture() : base(new ArchitectureConfiguration())
+ {
+ }
+
+ protected override void OnInitialize()
+ {
+ // 显式注册 Arch ECS 模块
+ this.UseArch();
+ }
+}
+
+// 初始化架构
+var architecture = new GameArchitecture();
+architecture.Initialize();
+```
+
+### 2. 带配置的注册
+
+```csharp
+public class GameArchitecture : Architecture
+{
+ protected override void OnInitialize()
+ {
+ // 带配置的注册
+ this.UseArch(options =>
+ {
+ options.WorldCapacity = 2000; // World 初始容量
+ options.EnableStatistics = true; // 启用统计信息
+ options.Priority = 50; // 模块优先级
+ });
+ }
+}
+```
+
+### 3. 定义组件
+
+组件是纯数据结构,使用 `struct` 定义:
+
+```csharp
+using System.Runtime.InteropServices;
+
+namespace MyGame.Components;
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Position(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Velocity(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Health(float current, float max)
+{
+ public float Current { get; set; } = current;
+ public float Max { get; set; } = max;
+}
+```
+
+### 4. 创建系统
+
+系统继承自 `ArchSystemAdapter`:
+
+```csharp
+using Arch.Core;
+using GFramework.Ecs.Arch;
+using MyGame.Components;
+
+namespace MyGame.Systems;
+
+///
+/// 移动系统 - 更新实体位置
+///
+public sealed class MovementSystem : ArchSystemAdapter
+{
+ private QueryDescription _query;
+
+ protected override void OnArchInitialize()
+ {
+ // 创建查询:查找所有同时拥有 Position 和 Velocity 组件的实体
+ _query = new QueryDescription()
+ .WithAll();
+ }
+
+ protected override void OnUpdate(in float deltaTime)
+ {
+ // 查询并更新所有符合条件的实体
+ World.Query(in _query, (ref Position pos, ref Velocity vel) =>
+ {
+ pos.X += vel.X * deltaTime;
+ pos.Y += vel.Y * deltaTime;
+ });
+ }
+}
+```
+
+### 5. 注册系统
+
+```csharp
+public class GameArchitecture : Architecture
+{
+ protected override void OnInitialize()
+ {
+ this.UseArch();
+
+ // 注册 ECS 系统
+ RegisterSystem();
+ }
+}
+```
+
+### 6. 创建实体
+
+```csharp
+using Arch.Core;
+using GFramework.Core.Abstractions.rule;
+using GFramework.SourceGenerators.Abstractions.rule;
+using MyGame.Components;
+
+[ContextAware]
+public partial class GameController
+{
+ public void Start()
+ {
+ // 获取 World
+ var world = this.GetService();
+
+ // 创建实体
+ var player = world.Create(
+ new Position(0, 0),
+ new Velocity(0, 0),
+ new Health(100, 100)
+ );
+
+ var enemy = world.Create(
+ new Position(10, 10),
+ new Velocity(-1, 0),
+ new Health(50, 50)
+ );
+ }
+}
+```
+
+### 7. 更新系统
+
+```csharp
+using GFramework.Ecs.Arch.Abstractions;
+
+public class GameLoop
+{
+ private IArchEcsModule _ecsModule;
+
+ public void Initialize()
+ {
+ // 获取 ECS 模块
+ _ecsModule = architecture.Context.GetService();
+ }
+
+ public void Update(float deltaTime)
+ {
+ // 更新所有 ECS 系统
+ _ecsModule.Update(deltaTime);
+ }
+}
+```
+
+## 配置选项
+
+### ArchOptions
+
+```csharp
+public sealed class ArchOptions
+{
+ ///
+ /// World 初始容量(默认:1000)
+ ///
+ public int WorldCapacity { get; set; } = 1000;
+
+ ///
+ /// 是否启用统计信息(默认:false)
+ ///
+ public bool EnableStatistics { get; set; } = false;
+
+ ///
+ /// 模块优先级(默认:50)
+ ///
+ public int Priority { get; set; } = 50;
+}
+```
+
+### 配置示例
+
+```csharp
+this.UseArch(options =>
+{
+ // 设置 World 初始容量
+ // 根据预期实体数量设置,避免频繁扩容
+ options.WorldCapacity = 2000;
+
+ // 启用统计信息(开发/调试时使用)
+ options.EnableStatistics = true;
+
+ // 设置模块优先级
+ // 数值越小,优先级越高
+ options.Priority = 50;
+});
+```
+
+## 核心概念
+
+### Entity(实体)
+
+实体是游戏世界中的基本对象,本质上是一个唯一标识符:
+
+```csharp
+// 创建空实体
+var entity = world.Create();
+
+// 创建带组件的实体
+var entity = world.Create(
+ new Position(0, 0),
+ new Velocity(1, 1)
+);
+
+// 销毁实体
+world.Destroy(entity);
+```
+
+### Component(组件)
+
+组件是纯数据结构,用于存储实体的状态:
+
+```csharp
+// 添加组件
+world.Add(entity, new Position(0, 0));
+
+// 检查组件
+if (world.Has(entity))
+{
+ // 获取组件引用(零 GC 分配)
+ ref var pos = ref world.Get(entity);
+ pos.X += 10;
+}
+
+// 设置组件(替换现有值)
+world.Set(entity, new Position(100, 100));
+
+// 移除组件
+world.Remove(entity);
+```
+
+### System(系统)
+
+系统包含游戏逻辑,处理具有特定组件组合的实体:
+
+```csharp
+public sealed class DamageSystem : ArchSystemAdapter
+{
+ private QueryDescription _query;
+
+ protected override void OnArchInitialize()
+ {
+ // 初始化查询
+ _query = new QueryDescription()
+ .WithAll();
+ }
+
+ protected override void OnUpdate(in float deltaTime)
+ {
+ // 处理伤害
+ World.Query(in _query, (Entity entity, ref Health health, ref Damage damage) =>
+ {
+ health.Current -= damage.Value * deltaTime;
+
+ if (health.Current <= 0)
+ {
+ health.Current = 0;
+ World.Remove(entity);
+ }
+ });
+ }
+}
+```
+
+### World(世界)
+
+World 是 ECS 的核心容器,管理所有实体和组件:
+
+```csharp
+// World 由 ArchEcsModule 自动创建和注册
+var world = this.GetService();
+
+// 获取实体数量
+var entityCount = world.Size;
+
+// 清空所有实体
+world.Clear();
+```
+
+## 系统适配器
+
+### ArchSystemAdapter
+
+`ArchSystemAdapter` 桥接 Arch.System.ISystem 到 GFramework 架构:
+
+```csharp
+public sealed class MySystem : ArchSystemAdapter
+{
+ // Arch 系统初始化
+ protected override void OnArchInitialize()
+ {
+ // 创建查询、初始化资源
+ }
+
+ // 更新前调用
+ protected override void OnBeforeUpdate(in float deltaTime)
+ {
+ // 预处理逻辑
+ }
+
+ // 主更新逻辑
+ protected override void OnUpdate(in float deltaTime)
+ {
+ // 处理实体
+ }
+
+ // 更新后调用
+ protected override void OnAfterUpdate(in float deltaTime)
+ {
+ // 后处理逻辑
+ }
+
+ // 资源清理
+ protected override void OnArchDispose()
+ {
+ // 清理资源
+ }
+}
+```
+
+### 访问 World
+
+在系统中可以直接访问 `World` 属性:
+
+```csharp
+public sealed class MySystem : ArchSystemAdapter
+{
+ protected override void OnUpdate(in float deltaTime)
+ {
+ // 访问 World
+ var entityCount = World.Size;
+
+ // 创建实体
+ var entity = World.Create(new Position(0, 0));
+
+ // 查询实体
+ var query = new QueryDescription().WithAll();
+ World.Query(in query, (ref Position pos) =>
+ {
+ // 处理逻辑
+ });
+ }
+}
+```
+
+### 访问框架服务
+
+`ArchSystemAdapter` 继承自 `AbstractSystem`,可以使用所有 GFramework 的扩展方法:
+
+```csharp
+public sealed class ServiceAccessSystem : ArchSystemAdapter
+{
+ protected override void OnUpdate(in float deltaTime)
+ {
+ // 获取 Model
+ var playerModel = this.GetModel();
+
+ // 获取 Utility
+ var timeUtility = this.GetUtility();
+
+ // 发送命令
+ this.SendCommand(new SaveGameCommand());
+
+ // 发送查询
+ var score = this.SendQuery(new GetScoreQuery());
+
+ // 发送事件
+ this.SendEvent(new GameOverEvent());
+ }
+}
+```
+
+## 查询实体
+
+### 基本查询
+
+```csharp
+// 查询:必须有 Position 和 Velocity
+var query = new QueryDescription()
+ .WithAll();
+
+World.Query(in query, (ref Position pos, ref Velocity vel) =>
+{
+ pos.X += vel.X * deltaTime;
+ pos.Y += vel.Y * deltaTime;
+});
+```
+
+### 过滤查询
+
+```csharp
+// 查询:必须有 Health,但不能有 Damage
+var query = new QueryDescription()
+ .WithAll()
+ .WithNone();
+
+World.Query(in query, (ref Health health) =>
+{
+ // 只处理没有受伤的实体
+});
+```
+
+### 可选组件查询
+
+```csharp
+// 查询:必须有 Position,可选 Velocity
+var query = new QueryDescription()
+ .WithAll()
+ .WithAny();
+
+World.Query(in query, (Entity entity, ref Position pos) =>
+{
+ // 处理逻辑
+});
+```
+
+### 访问实体 ID
+
+```csharp
+var query = new QueryDescription().WithAll();
+
+World.Query(in query, (Entity entity, ref Position pos) =>
+{
+ // 可以访问实体 ID
+ Console.WriteLine($"Entity {entity.Id}: ({pos.X}, {pos.Y})");
+
+ // 可以对实体进行操作
+ if (pos.X > 100)
+ {
+ World.Destroy(entity);
+ }
+});
+```
+
+## 系统优先级
+
+系统按照优先级顺序执行,数值越小优先级越高:
+
+```csharp
+using GFramework.Core.Abstractions.bases;
+using GFramework.SourceGenerators.Abstractions.bases;
+
+// 使用 Priority 特性设置优先级
+[Priority(10)] // 高优先级,先执行
+public sealed class InputSystem : ArchSystemAdapter
+{
+ // ...
+}
+
+[Priority(20)] // 中优先级
+public sealed class MovementSystem : ArchSystemAdapter
+{
+ // ...
+}
+
+[Priority(30)] // 低优先级,后执行
+public sealed class RenderSystem : ArchSystemAdapter
+{
+ // ...
+}
+```
+
+执行顺序:InputSystem → MovementSystem → RenderSystem
+
+## 性能优化
+
+### 1. 使用 struct 组件
+
+```csharp
+// ✅ 推荐:使用 struct
+[StructLayout(LayoutKind.Sequential)]
+public struct Position(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+// ❌ 不推荐:使用 class
+public class Position
+{
+ public float X { get; set; }
+ public float Y { get; set; }
+}
+```
+
+### 2. 缓存查询
+
+```csharp
+public class OptimizedSystem : ArchSystemAdapter
+{
+ // ✅ 推荐:缓存查询
+ private QueryDescription _cachedQuery;
+
+ protected override void OnArchInitialize()
+ {
+ _cachedQuery = new QueryDescription()
+ .WithAll();
+ }
+
+ protected override void OnUpdate(in float deltaTime)
+ {
+ World.Query(in _cachedQuery, (ref Position pos, ref Velocity vel) =>
+ {
+ pos.X += vel.X * deltaTime;
+ pos.Y += vel.Y * deltaTime;
+ });
+ }
+}
+```
+
+### 3. 使用 ref 访问组件
+
+```csharp
+// ✅ 推荐:使用 ref 避免复制
+World.Query(in query, (ref Position pos, ref Velocity vel) =>
+{
+ pos.X += vel.X; // 直接修改,零 GC
+});
+
+// ❌ 不推荐:不使用 ref
+World.Query(in query, (Position pos, Velocity vel) =>
+{
+ pos.X += vel.X; // 复制值,修改不会生效
+});
+```
+
+### 4. 组件大小优化
+
+```csharp
+// ✅ 推荐:小而专注的组件
+public struct Position(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+public struct Velocity(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+// ❌ 不推荐:大而全的组件
+public struct Transform
+{
+ public float X, Y, Z;
+ public float RotationX, RotationY, RotationZ;
+ public float ScaleX, ScaleY, ScaleZ;
+ public float VelocityX, VelocityY, VelocityZ;
+ // ... 太多数据
+}
+```
+
+## 最佳实践
+
+### 1. 组件设计原则
+
+- 使用 `struct` 而不是 `class`
+- 只包含数据,不包含逻辑
+- 使用 `[StructLayout(LayoutKind.Sequential)]` 优化内存布局
+- 保持组件小而专注
+
+### 2. 系统设计原则
+
+- 单一职责:每个系统只负责一件事
+- 缓存查询:在 `OnArchInitialize` 中创建查询
+- 使用 ref:访问组件时使用 ref 参数
+- 批量处理:一次查询处理所有实体
+
+### 3. 标签组件
+
+使用空结构体作为标签来分类实体:
+
+```csharp
+// 定义标签组件
+public struct PlayerTag { }
+public struct EnemyTag { }
+public struct DeadTag { }
+
+// 使用标签过滤实体
+var query = new QueryDescription()
+ .WithAll()
+ .WithNone();
+```
+
+### 4. 与传统架构结合
+
+```csharp
+// ECS 系统可以访问 Model
+public class EnemySpawnSystem : ArchSystemAdapter
+{
+ protected override void OnUpdate(in float deltaTime)
+ {
+ var gameState = this.GetModel();
+
+ // 根据关卡生成敌人
+ for (int i = 0; i < gameState.Level; i++)
+ {
+ World.Create(
+ new Position(Random.Shared.Next(0, 100), 0),
+ new Velocity(0, -1),
+ new Health(50, 50)
+ );
+ }
+ }
+}
+```
+
+## 常见问题
+
+### Q: 如何在运行时动态添加/移除组件?
+
+A: Arch 支持运行时修改实体的组件:
+
+```csharp
+// 动态添加组件
+if (pos.X > 100 && !World.Has(entity))
+{
+ World.Add(entity, new FastTag());
+}
+
+// 动态移除组件
+if (pos.X < 0 && World.Has(entity))
+{
+ World.Remove(entity);
+}
+```
+
+### Q: 如何处理实体之间的交互?
+
+A: 使用嵌套查询或事件:
+
+```csharp
+// 方式 1:嵌套查询
+World.Query(in playerQuery, (Entity player, ref Position playerPos) =>
+{
+ World.Query(in enemyQuery, (Entity enemy, ref Position enemyPos) =>
+ {
+ // 检测碰撞
+ });
+});
+
+// 方式 2:使用事件
+this.SendEvent(new CollisionEvent
+{
+ Entity1 = player,
+ Entity2 = enemy
+});
+```
+
+### Q: 如何调试 ECS 系统?
+
+A: 使用日志和统计信息:
+
+```csharp
+protected override void OnUpdate(in float deltaTime)
+{
+ // 打印实体数量
+ Console.WriteLine($"Total entities: {World.Size}");
+
+ // 查询特定实体
+ var query = new QueryDescription().WithAll();
+ var count = 0;
+ World.Query(in query, (Entity entity, ref Position pos) =>
+ {
+ count++;
+ Console.WriteLine($"Entity {entity.Id}: ({pos.X}, {pos.Y})");
+ });
+}
+```
+
+## 相关资源
+
+- [Arch.Core 官方文档](https://github.com/genaray/Arch)
+- [ECS 概述](./index.md)
+- [ECS 最佳实践](./best-practices.md)
+- [性能优化指南](./performance.md)
+
+---
+
+**许可证**:MIT License
diff --git a/docs/zh-CN/ecs/index.md b/docs/zh-CN/ecs/index.md
new file mode 100644
index 0000000..63100e6
--- /dev/null
+++ b/docs/zh-CN/ecs/index.md
@@ -0,0 +1,297 @@
+---
+title: ECS 系统集成
+description: GFramework 的 ECS(Entity Component System)集成方案,支持多种 ECS 框架。
+---
+
+# ECS 系统集成
+
+## 概述
+
+GFramework 提供了灵活的 ECS(Entity Component System)集成方案,允许你根据项目需求选择合适的 ECS 框架。ECS
+是一种数据驱动的架构模式,特别适合处理大量相似实体的场景。
+
+## 什么是 ECS?
+
+ECS(Entity Component System)是一种架构模式,将游戏对象分解为三个核心概念:
+
+- **Entity(实体)**:游戏世界中的基本对象,本质上是一个唯一标识符
+- **Component(组件)**:纯数据结构,存储实体的状态
+- **System(系统)**:包含游戏逻辑,处理具有特定组件组合的实体
+
+### ECS 的优势
+
+- **高性能**:数据局部性好,缓存友好
+- **可扩展**:通过组合组件轻松创建新实体类型
+- **并行处理**:系统之间相互独立,易于并行化
+- **数据驱动**:逻辑与数据分离,便于序列化和网络同步
+
+### 何时使用 ECS?
+
+**适合使用 ECS 的场景**:
+
+- 大量相似实体(敌人、子弹、粒子)
+- 需要高性能批量处理
+- 复杂的实体组合和变化
+- 需要并行处理的系统
+
+**不适合使用 ECS 的场景**:
+
+- 全局状态管理
+- 单例服务
+- UI 逻辑
+- 游戏流程控制
+
+## 支持的 ECS 框架
+
+GFramework 采用可选集成的设计,你可以根据需求选择合适的 ECS 框架:
+
+### Arch ECS(推荐)
+
+[Arch](https://github.com/genaray/Arch) 是一个高性能的 C# ECS 框架,具有以下特点:
+
+- ✅ **极致性能**:基于 Archetype 的内存布局,零 GC 分配
+- ✅ **简单易用**:清晰的 API,易于上手
+- ✅ **功能完整**:支持查询、过滤、并行处理等高级特性
+- ✅ **活跃维护**:社区活跃,持续更新
+
+**安装方式**:
+
+```bash
+dotnet add package GeWuYou.GFramework.Ecs.Arch
+```
+
+**文档链接**:[Arch ECS 集成指南](./arch.md)
+
+### 其他 ECS 框架
+
+GFramework 的设计允许集成其他 ECS 框架,未来可能支持:
+
+- **DefaultEcs**:轻量级 ECS 框架
+- **Entitas**:成熟的 ECS 框架,Unity 生态常用
+- **自定义 ECS**:你可以基于 GFramework 的模块系统实现自己的 ECS 集成
+
+## 快速开始
+
+### 1. 选择 ECS 框架
+
+根据项目需求选择合适的 ECS 框架。对于大多数项目,我们推荐使用 Arch ECS。
+
+### 2. 安装集成包
+
+```bash
+# 安装 Arch ECS 集成包
+dotnet add package GeWuYou.GFramework.Ecs.Arch
+```
+
+### 3. 注册 ECS 模块
+
+```csharp
+using GFramework.Core.architecture;
+using GFramework.Ecs.Arc;
+
+public class GameArchitecture : Architecture
+{
+ public GameArchitecture() : base(new ArchitectureConfiguration())
+ {
+ }
+
+ protected override void OnInitialize()
+ {
+ // 显式注册 Arch ECS 模块
+ this.UseArch(options =>
+ {
+ options.WorldCapacity = 2000;
+ options.EnableStatistics = true;
+ });
+ }
+}
+```
+
+### 4. 定义组件
+
+```csharp
+using System.Runtime.InteropServices;
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Position(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Velocity(float x, float y)
+{
+ public float X { get; set; } = x;
+ public float Y { get; set; } = y;
+}
+```
+
+### 5. 创建系统
+
+```csharp
+using Arch.Core;
+using GFramework.Ecs.Arch;
+
+public sealed class MovementSystem : ArchSystemAdapter
+{
+ private QueryDescription _query;
+
+ protected override void OnArchInitialize()
+ {
+ _query = new QueryDescription()
+ .WithAll();
+ }
+
+ protected override void OnUpdate(in float deltaTime)
+ {
+ World.Query(in _query, (ref Position pos, ref Velocity vel) =>
+ {
+ pos.X += vel.X * deltaTime;
+ pos.Y += vel.Y * deltaTime;
+ });
+ }
+}
+```
+
+### 6. 注册系统
+
+```csharp
+public class GameArchitecture : Architecture
+{
+ protected override void OnInitialize()
+ {
+ this.UseArch();
+
+ // 注册 ECS 系统
+ RegisterSystem();
+ }
+}
+```
+
+## 设计理念
+
+### 显式集成
+
+GFramework 采用显式集成的设计,而不是自动注册:
+
+```csharp
+// ✅ 显式注册 - 清晰、可控
+public class GameArchitecture : Architecture
+{
+ protected override void OnInitialize()
+ {
+ this.UseArch(); // 明确表示使用 Arch ECS
+ }
+}
+
+// ❌ 自动注册 - 隐式、难以控制
+// 只需引入包,自动注册(不推荐)
+```
+
+**优势**:
+
+- 清晰的依赖关系
+- 更好的 IDE 支持
+- 易于测试和调试
+- 符合 .NET 生态习惯
+
+### 零依赖原则
+
+如果你不使用 ECS,GFramework.Core 包不会引入任何 ECS 相关的依赖:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+### 模块化设计
+
+ECS 集成基于 GFramework 的模块系统:
+
+```csharp
+// ECS 模块实现 IServiceModule 接口
+public sealed class ArchEcsModule : IArchEcsModule
+{
+ public string ModuleName => nameof(ArchEcsModule);
+ public int Priority => 50;
+ public bool IsEnabled { get; }
+
+ public void Register(IIocContainer container) { }
+ public void Initialize() { }
+ public ValueTask DestroyAsync() { }
+ public void Update(float deltaTime) { }
+}
+```
+
+## 与传统架构结合
+
+ECS 可以与 GFramework 的传统架构(Model、System、Utility)无缝结合:
+
+```csharp
+// Model 存储全局状态
+public class GameStateModel : AbstractModel
+{
+ public int Score { get; set; }
+ public int Level { get; set; }
+}
+
+// ECS System 处理实体逻辑
+public class EnemySpawnSystem : ArchSystemAdapter
+{
+ protected override void OnUpdate(in float deltaTime)
+ {
+ // 访问 Model
+ var gameState = this.GetModel();
+
+ // 根据关卡生成敌人
+ for (int i = 0; i < gameState.Level; i++)
+ {
+ World.Create(
+ new Position(Random.Shared.Next(0, 100), 0),
+ new Velocity(0, -1),
+ new Health(50, 50)
+ );
+ }
+ }
+}
+
+// 传统 System 处理游戏逻辑
+public class ScoreSystem : AbstractSystem
+{
+ protected override void OnInit()
+ {
+ this.RegisterEvent(OnEnemyDestroyed);
+ }
+
+ private void OnEnemyDestroyed(EnemyDestroyedEvent e)
+ {
+ var gameState = this.GetModel();
+ gameState.Score += 100;
+ }
+}
+```
+
+## 下一步
+
+- [Arch ECS 集成指南](./arch.md) - 详细的 Arch ECS 使用文档
+- [ECS 最佳实践](./best-practices.md) - ECS 设计模式和优化技巧
+- [性能优化](./performance.md) - ECS 性能优化指南
+
+## 相关资源
+
+- [Architecture 架构系统](../core/architecture.md)
+- [System 系统](../core/system.md)
+- [事件系统](../core/events.md)
+
+---
+
+**许可证**:MIT License