refactor(architecture): 重构架构初始化和销毁机制

- 将Init方法统一重命名为Initialize方法以提高一致性
- 修改Architecture类中的组件注册逻辑,优化去重判断
- 更新ECS系统基础类以使用新的初始化接口
- 重构EcsWorld类使用属性自动实现而非私有字段
- 移除过时的EcsUsageExample示例文件
- 更新相关测试类以匹配新的初始化方法命名
- 改进代码注释和文档字符串格式
This commit is contained in:
GeWuYou 2026-02-23 10:54:35 +08:00 committed by gewuyou
parent 35845be93f
commit 3db89ab498
33 changed files with 112 additions and 180 deletions

View File

@ -10,7 +10,7 @@ namespace GFramework.Core.Abstractions.architecture;
/// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取 /// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取
/// 业务操作通过 ArchitectureRuntime 提供 /// 业务操作通过 ArchitectureRuntime 提供
/// </summary> /// </summary>
public interface IArchitecture : IAsyncInitializable public interface IArchitecture : IAsyncInitializable, IAsyncDestroyable, IInitializable, IDestroyable
{ {
/// <summary> /// <summary>
/// 获取架构上下文 /// 获取架构上下文
@ -25,22 +25,6 @@ public interface IArchitecture : IAsyncInitializable
/// </value> /// </value>
Action<IServiceCollection>? Configurator { get; } Action<IServiceCollection>? Configurator { get; }
/// <summary>
/// 初始化方法,用于执行对象的初始化操作
/// </summary>
/// <remarks>
/// 该方法通常用于设置初始状态、初始化成员变量或执行必要的预处理操作
/// </remarks>
void Initialize();
/// <summary>
/// 销毁方法,用于执行对象的清理和销毁操作
/// </summary>
/// <remarks>
/// 该方法通常用于释放资源、清理内存或执行必要的清理操作
/// </remarks>
void Destroy();
/// <summary> /// <summary>
/// 注册系统实例到架构中 /// 注册系统实例到架构中
/// </summary> /// </summary>

View File

@ -8,5 +8,5 @@ public interface IInitializable
/// <summary> /// <summary>
/// 初始化组件 /// 初始化组件
/// </summary> /// </summary>
void Init(); void Initialize();
} }

View File

@ -321,7 +321,7 @@ public class TestSystemV2 : ISystem
return _context; return _context;
} }
public void Init() public void Initialize()
{ {
} }
@ -349,7 +349,7 @@ public class TestModelV2 : IModel
return _context; return _context;
} }
public void Init() public void Initialize()
{ {
} }

View File

@ -11,12 +11,12 @@ public class AsyncTestArchitecture : TestArchitectureBase
/// <summary> /// <summary>
/// 异步初始化架构 /// 异步初始化架构
/// </summary> /// </summary>
protected override void Init() protected override void OnInitialize()
{ {
// 注册模型 // 注册模型
RegisterModel(new AsyncTestModel()); RegisterModel(new AsyncTestModel());
// 注册系统 // 注册系统
RegisterSystem(new AsyncTestSystem()); RegisterSystem(new AsyncTestSystem());
base.Init(); base.OnInitialize();
} }
} }

View File

@ -222,7 +222,7 @@ public class TestArchitecture : Architecture
/// <summary> /// <summary>
/// 初始化方法,当前为空实现 /// 初始化方法,当前为空实现
/// </summary> /// </summary>
protected override void Init() protected override void OnInitialize()
{ {
} }
} }

View File

@ -11,10 +11,10 @@ public sealed class SyncTestArchitecture : TestArchitectureBase
/// <summary> /// <summary>
/// 初始化架构组件,注册模型、系统并设置事件监听器 /// 初始化架构组件,注册模型、系统并设置事件监听器
/// </summary> /// </summary>
protected override void Init() protected override void OnInitialize()
{ {
RegisterModel(new TestModel()); RegisterModel(new TestModel());
RegisterSystem(new TestSystem()); RegisterSystem(new TestSystem());
base.Init(); base.OnInitialize();
} }
} }

View File

@ -37,7 +37,7 @@ public abstract class TestArchitectureBase : Architecture
/// <summary> /// <summary>
/// 初始化架构组件,注册模型、系统并设置事件监听器 /// 初始化架构组件,注册模型、系统并设置事件监听器
/// </summary> /// </summary>
protected override void Init() protected override void OnInitialize()
{ {
InitCalled = true; InitCalled = true;
_postRegistrationHook?.Invoke(this); _postRegistrationHook?.Invoke(this);

View File

@ -53,7 +53,7 @@ public class EcsAdvancedTests
{ {
var system = (IEcsSystem)Activator.CreateInstance(systemType)!; var system = (IEcsSystem)Activator.CreateInstance(systemType)!;
((IContextAware)system).SetContext(_context!); ((IContextAware)system).SetContext(_context!);
system.Init(); system.Initialize();
systems.Add(system); systems.Add(system);
_container.RegisterPlurality(system); _container.RegisterPlurality(system);
} }
@ -65,7 +65,7 @@ public class EcsAdvancedTests
{ {
var runner = new EcsSystemRunner(); var runner = new EcsSystemRunner();
((IContextAware)runner).SetContext(_context!); ((IContextAware)runner).SetContext(_context!);
runner.Init(); runner.Initialize();
return runner; return runner;
} }
@ -220,7 +220,7 @@ public class EcsAdvancedTests
foreach (var system in new[] { systemA, systemB, systemC }) foreach (var system in new[] { systemA, systemB, systemC })
{ {
((IContextAware)system).SetContext(_context!); ((IContextAware)system).SetContext(_context!);
system.Init(); system.Initialize();
_container.RegisterPlurality(system); _container.RegisterPlurality(system);
} }
@ -247,7 +247,7 @@ public class EcsAdvancedTests
var movementSystem = new MovementSystem(); var movementSystem = new MovementSystem();
((IContextAware)movementSystem).SetContext(_context!); ((IContextAware)movementSystem).SetContext(_context!);
movementSystem.Init(); movementSystem.Initialize();
_container.RegisterPlurality(movementSystem); _container.RegisterPlurality(movementSystem);
_container.Register(new List<IEcsSystem> { movementSystem } as IReadOnlyList<IEcsSystem>); _container.Register(new List<IEcsSystem> { movementSystem } as IReadOnlyList<IEcsSystem>);

View File

@ -68,7 +68,7 @@ public class EcsBasicTests
{ {
var system = (IEcsSystem)Activator.CreateInstance(systemType)!; var system = (IEcsSystem)Activator.CreateInstance(systemType)!;
system.SetContext(_context!); system.SetContext(_context!);
system.Init(); system.Initialize();
systems.Add(system); systems.Add(system);
_container.RegisterPlurality(system); _container.RegisterPlurality(system);
} }

View File

@ -68,7 +68,7 @@ public class EcsIntegrationTests
{ {
var system = (IEcsSystem)Activator.CreateInstance(systemType)!; var system = (IEcsSystem)Activator.CreateInstance(systemType)!;
system.SetContext(_context!); system.SetContext(_context!);
system.Init(); system.Initialize();
systems.Add(system); systems.Add(system);
_container.RegisterPlurality(system); _container.RegisterPlurality(system);
} }

View File

@ -214,7 +214,7 @@ public class MediatorComprehensiveTests
var results = new List<int>(); var results = new List<int>();
// 流应该在100ms后被取消TaskCanceledException 继承自 OperationCanceledException // 流应该在100ms后被取消TaskCanceledException 继承自 OperationCanceledException
Assert.ThrowsAsync<OperationCanceledException>(async () => Assert.CatchAsync<OperationCanceledException>(async () =>
{ {
await foreach (var item in stream) await foreach (var item in stream)
{ {

View File

@ -30,8 +30,8 @@ public sealed class AsyncTestModel : AbstractModel, IAsyncInitializable
/// <exception cref="InvalidOperationException">当该方法被调用时抛出异常</exception> /// <exception cref="InvalidOperationException">当该方法被调用时抛出异常</exception>
public void Init() public void Init()
{ {
// sync Init 不应该被调用 // sync OnInitialize 不应该被调用
throw new InvalidOperationException("Sync Init should not be called"); throw new InvalidOperationException("Sync OnInitialize should not be called");
} }
/// <summary> /// <summary>

View File

@ -15,7 +15,7 @@ public sealed class FailingModel : IModel
/// 该方法会故意抛出InvalidOperationException异常 /// 该方法会故意抛出InvalidOperationException异常
/// </summary> /// </summary>
/// <exception cref="InvalidOperationException">总是抛出此异常以模拟初始化失败</exception> /// <exception cref="InvalidOperationException">总是抛出此异常以模拟初始化失败</exception>
public void Init() public void Initialize()
{ {
throw new InvalidOperationException("Model init failed intentionally"); throw new InvalidOperationException("Model init failed intentionally");
} }

View File

@ -18,7 +18,7 @@ public sealed class TestModel : AbstractModel, ITestModel
/// <summary> /// <summary>
/// 初始化模型 /// 初始化模型
/// </summary> /// </summary>
public void Init() public void Initialize()
{ {
Initialized = true; Initialized = true;
} }

View File

@ -114,7 +114,7 @@ public class StateMachineSystemTests
Assert.Throws<InvalidOperationException>(() => state1.GetContext()); Assert.Throws<InvalidOperationException>(() => state1.GetContext());
Assert.Throws<InvalidOperationException>(() => state2.GetContext()); Assert.Throws<InvalidOperationException>(() => state2.GetContext());
_stateMachine.Init(); _stateMachine.Initialize();
Assert.That(state1.GetContext(), Is.SameAs(_context)); Assert.That(state1.GetContext(), Is.SameAs(_context));
Assert.That(state2.GetContext(), Is.SameAs(_context)); Assert.That(state2.GetContext(), Is.SameAs(_context));
@ -129,7 +129,7 @@ public class StateMachineSystemTests
var state = new TestStateV5(); var state = new TestStateV5();
_stateMachine!.Register(state); _stateMachine!.Register(state);
_stateMachine.Init(); _stateMachine.Initialize();
} }
/// <summary> /// <summary>
@ -173,7 +173,7 @@ public class StateMachineSystemTests
_stateMachine!.Register(state1); _stateMachine!.Register(state1);
_stateMachine.Register(state2); _stateMachine.Register(state2);
_stateMachine.Init(); _stateMachine.Initialize();
await _stateMachine.ChangeToAsync<TestStateV5>(); await _stateMachine.ChangeToAsync<TestStateV5>();
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
@ -203,7 +203,7 @@ public class StateMachineSystemTests
_stateMachine!.Register(state1); _stateMachine!.Register(state1);
_stateMachine.Register(state2); _stateMachine.Register(state2);
_stateMachine.Init(); _stateMachine.Initialize();
await _stateMachine.ChangeToAsync<TestStateV5>(); await _stateMachine.ChangeToAsync<TestStateV5>();
eventReceived = false; eventReceived = false;
@ -230,7 +230,7 @@ public class StateMachineSystemTests
_stateMachine!.Register(state1); _stateMachine!.Register(state1);
_stateMachine.Register(state2); _stateMachine.Register(state2);
_stateMachine.Init(); _stateMachine.Initialize();
await _stateMachine.ChangeToAsync<TestStateV5>(); await _stateMachine.ChangeToAsync<TestStateV5>();
await _stateMachine.ChangeToAsync<TestStateV5_2>(); await _stateMachine.ChangeToAsync<TestStateV5_2>();
await _stateMachine.ChangeToAsync<TestStateV5>(); await _stateMachine.ChangeToAsync<TestStateV5>();

View File

@ -30,10 +30,10 @@ public sealed class AsyncTestSystem : ISystem, IAsyncInitializable
return _context; return _context;
} }
public void Init() public void Initialize()
{ {
// 同步 Init 不应该被调用 // 同步 OnInitialize 不应该被调用
throw new InvalidOperationException("Sync Init should not be called"); throw new InvalidOperationException("Sync OnInitialize should not be called");
} }
public void Destroy() public void Destroy()

View File

@ -45,7 +45,7 @@ public sealed class TestSystem : ISystem
/// <summary> /// <summary>
/// 初始化系统 /// 初始化系统
/// </summary> /// </summary>
public void Init() public void Initialize()
{ {
Initialized = true; Initialized = true;
} }

View File

@ -61,11 +61,11 @@ public class AbstractContextUtilityTests
{ {
var utility = new TestContextUtilityV1(); var utility = new TestContextUtilityV1();
Assert.That(utility.Initialized, Is.False, "Utility should not be initialized before Init"); Assert.That(utility.Initialized, Is.False, "Utility should not be initialized before OnInitialize");
utility.Init(); utility.Initialize();
Assert.That(utility.Initialized, Is.True, "Utility should be initialized after Init"); Assert.That(utility.Initialized, Is.True, "Utility should be initialized after OnInitialize");
} }
/// <summary> /// <summary>
@ -76,11 +76,11 @@ public class AbstractContextUtilityTests
{ {
var utility = new TestContextUtilityV1(); var utility = new TestContextUtilityV1();
Assert.That(utility.GetLogger(), Is.Null, "Logger should be null before Init"); Assert.That(utility.GetLogger(), Is.Null, "Logger should be null before OnInitialize");
utility.Init(); utility.Initialize();
Assert.That(utility.GetLogger(), Is.Not.Null, "Logger should be set after Init"); Assert.That(utility.GetLogger(), Is.Not.Null, "Logger should be set after OnInitialize");
} }
/// <summary> /// <summary>
@ -91,11 +91,11 @@ public class AbstractContextUtilityTests
{ {
var utility = new TestContextUtilityV1(); var utility = new TestContextUtilityV1();
Assert.That(utility.InitCalled, Is.False, "InitCalled should be false before Init"); Assert.That(utility.InitCalled, Is.False, "InitCalled should be false before OnInitialize");
utility.Init(); utility.Initialize();
Assert.That(utility.InitCalled, Is.True, "InitCalled should be true after Init"); Assert.That(utility.InitCalled, Is.True, "InitCalled should be true after OnInitialize");
} }
/// <summary> /// <summary>
@ -106,7 +106,7 @@ public class AbstractContextUtilityTests
{ {
var utility = new TestContextUtilityV1(); var utility = new TestContextUtilityV1();
utility.Init(); utility.Initialize();
Assert.That(utility.Destroyed, Is.False, "Utility should not be destroyed before Destroy"); Assert.That(utility.Destroyed, Is.False, "Utility should not be destroyed before Destroy");
utility.Destroy(); utility.Destroy();
@ -156,7 +156,7 @@ public class AbstractContextUtilityTests
Assert.That(utility.Initialized, Is.False); Assert.That(utility.Initialized, Is.False);
Assert.That(utility.CustomInitializationDone, Is.False); Assert.That(utility.CustomInitializationDone, Is.False);
utility.Init(); utility.Initialize();
Assert.That(utility.Initialized, Is.True); Assert.That(utility.Initialized, Is.True);
Assert.That(utility.CustomInitializationDone, Is.True); Assert.That(utility.CustomInitializationDone, Is.True);
@ -175,7 +175,7 @@ public class AbstractContextUtilityTests
Assert.That(utility.Destroyed, Is.False); Assert.That(utility.Destroyed, Is.False);
// 初始化 // 初始化
utility.Init(); utility.Initialize();
Assert.That(utility.Initialized, Is.True); Assert.That(utility.Initialized, Is.True);
Assert.That(utility.Destroyed, Is.False); Assert.That(utility.Destroyed, Is.False);
@ -194,7 +194,7 @@ public class AbstractContextUtilityTests
var utility = new TestContextUtilityV1(); var utility = new TestContextUtilityV1();
// 第一次初始化和销毁 // 第一次初始化和销毁
utility.Init(); utility.Initialize();
Assert.That(utility.Initialized, Is.True); Assert.That(utility.Initialized, Is.True);
utility.Destroy(); utility.Destroy();
Assert.That(utility.Destroyed, Is.True); Assert.That(utility.Destroyed, Is.True);
@ -203,7 +203,7 @@ public class AbstractContextUtilityTests
utility.Destroyed = false; utility.Destroyed = false;
// 第二次初始化和销毁 // 第二次初始化和销毁
utility.Init(); utility.Initialize();
Assert.That(utility.Initialized, Is.True); Assert.That(utility.Initialized, Is.True);
utility.Destroy(); utility.Destroy();
Assert.That(utility.Destroyed, Is.True); Assert.That(utility.Destroyed, Is.True);

View File

@ -261,15 +261,11 @@ public abstract class Architecture(
} }
// 处理销毁(支持 IDestroyable 或 IAsyncDestroyable // 处理销毁(支持 IDestroyable 或 IAsyncDestroyable
if (component is IDestroyable or IAsyncDestroyable) if (component is not (IDestroyable or IAsyncDestroyable)) return;
{ // 原子去重HashSet.Add 返回 true 表示添加成功(之前不存在)
// 原子去重HashSet.Add 返回 true 表示添加成功(之前不存在) if (!_disposableSet.Add(component)) return;
if (_disposableSet.Add(component)) _disposables.Add(component);
{ _logger.Trace($"Registered {component.GetType().Name} for destruction");
_disposables.Add(component);
_logger.Trace($"Registered {component.GetType().Name} for destruction");
}
}
} }
/// <summary> /// <summary>
@ -354,13 +350,13 @@ public abstract class Architecture(
if (asyncMode && component is IAsyncInitializable asyncInit) if (asyncMode && component is IAsyncInitializable asyncInit)
await asyncInit.InitializeAsync(); await asyncInit.InitializeAsync();
else else
component.Init(); component.Initialize();
} }
/// <summary> /// <summary>
/// 抽象初始化方法,由子类重写以进行自定义初始化操作 /// 抽象初始化方法,由子类重写以进行自定义初始化操作
/// </summary> /// </summary>
protected abstract void Init(); protected abstract void OnInitialize();
/// <summary> /// <summary>
/// 异步销毁架构及所有组件 /// 异步销毁架构及所有组件
@ -663,10 +659,10 @@ public abstract class Architecture(
// 执行服务钩子 // 执行服务钩子
Container.ExecuteServicesHook(Configurator); Container.ExecuteServicesHook(Configurator);
// === 用户 Init === // === 用户 OnInitialize ===
_logger.Debug("Calling user Init()"); _logger.Debug("Calling user OnInitialize()");
Init(); OnInitialize();
_logger.Debug("User Init() completed"); _logger.Debug("User OnInitialize() completed");
// === 组件初始化阶段 === // === 组件初始化阶段 ===
await InitializeAllComponentsAsync(asyncMode); await InitializeAllComponentsAsync(asyncMode);

View File

@ -90,7 +90,7 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
var mediator = Mediator; var mediator = Mediator;
if (mediator == null) if (mediator == null)
throw new InvalidOperationException( throw new InvalidOperationException(
"Mediator not registered. Call EnableMediator() in your Architecture.Init() method."); "Mediator not registered. Call EnableMediator() in your Architecture.OnInitialize() method.");
return await mediator.Send(request, cancellationToken); return await mediator.Send(request, cancellationToken);
} }

View File

@ -1,5 +1,6 @@
using Arch.Core; using Arch.Core;
using GFramework.Core.Abstractions.ecs; using GFramework.Core.Abstractions.ecs;
using GFramework.Core.extensions;
using GFramework.Core.system; using GFramework.Core.system;
namespace GFramework.Core.ecs; namespace GFramework.Core.ecs;
@ -34,7 +35,7 @@ public abstract class EcsSystemBase : AbstractSystem, IEcsSystem
/// </summary> /// </summary>
protected override void OnInit() protected override void OnInit()
{ {
EcsWorld = Context.GetService<EcsWorld>() ?? throw new InvalidOperationException( EcsWorld = this.GetService<EcsWorld>() ?? throw new InvalidOperationException(
"EcsWorld not found in context. Make sure ECS is properly initialized."); "EcsWorld not found in context. Make sure ECS is properly initialized.");
OnEcsInit(); OnEcsInit();

View File

@ -1,4 +1,5 @@
using GFramework.Core.Abstractions.ecs; using GFramework.Core.Abstractions.ecs;
using GFramework.Core.extensions;
using GFramework.Core.system; using GFramework.Core.system;
namespace GFramework.Core.ecs; namespace GFramework.Core.ecs;
@ -17,8 +18,8 @@ public sealed class EcsSystemRunner : AbstractSystem
protected override void OnInit() protected override void OnInit()
{ {
// 从容器获取所有已注册的ECS系统 // 从容器获取所有已注册的ECS系统
var systemsList = Context.GetService<IReadOnlyList<IEcsSystem>>(); var systemsList = this.GetService<IReadOnlyList<IEcsSystem>>();
if (systemsList != null && systemsList.Count > 0) if (systemsList is { Count: > 0 })
{ {
// 按优先级排序 // 按优先级排序
_systems.AddRange(systemsList.OrderBy(s => s.Priority)); _systems.AddRange(systemsList.OrderBy(s => s.Priority));

View File

@ -8,25 +8,24 @@ namespace GFramework.Core.ecs;
/// </summary> /// </summary>
public sealed class EcsWorld : IEcsWorld public sealed class EcsWorld : IEcsWorld
{ {
private readonly World _world = World.Create();
private bool _disposed; private bool _disposed;
/// <summary> /// <summary>
/// 获取内部的Arch World实例 /// 获取内部的Arch World实例
/// </summary> /// </summary>
public World InternalWorld => _world; public World InternalWorld { get; } = World.Create();
/// <summary> /// <summary>
/// 当前实体数量 /// 当前实体数量
/// </summary> /// </summary>
public int EntityCount => _world.Size; public int EntityCount => InternalWorld.Size;
/// <summary> /// <summary>
/// 创建一个新实体 /// 创建一个新实体
/// </summary> /// </summary>
public Entity CreateEntity(params ComponentType[] types) public Entity CreateEntity(params ComponentType[] types)
{ {
return _world.Create(types); return InternalWorld.Create(types);
} }
/// <summary> /// <summary>
@ -34,7 +33,7 @@ public sealed class EcsWorld : IEcsWorld
/// </summary> /// </summary>
public void DestroyEntity(Entity entity) public void DestroyEntity(Entity entity)
{ {
_world.Destroy(entity); InternalWorld.Destroy(entity);
} }
/// <summary> /// <summary>
@ -42,7 +41,7 @@ public sealed class EcsWorld : IEcsWorld
/// </summary> /// </summary>
public bool IsAlive(Entity entity) public bool IsAlive(Entity entity)
{ {
return _world.IsAlive(entity); return InternalWorld.IsAlive(entity);
} }
/// <summary> /// <summary>
@ -50,7 +49,7 @@ public sealed class EcsWorld : IEcsWorld
/// </summary> /// </summary>
public void Clear() public void Clear()
{ {
_world.Clear(); InternalWorld.Clear();
} }
/// <summary> /// <summary>
@ -60,7 +59,7 @@ public sealed class EcsWorld : IEcsWorld
{ {
if (_disposed) return; if (_disposed) return;
World.Destroy(_world); World.Destroy(InternalWorld);
_disposed = true; _disposed = true;
} }
} }

View File

@ -1,16 +1,19 @@
namespace GFramework.Core.ecs.components; namespace GFramework.Core.ecs.components;
/// <summary> /// <summary>
/// 位置组件 /// 位置组件,用于表示实体在二维空间中的坐标位置。
/// </summary> /// </summary>
public struct Position /// <param name="x">X轴坐标值</param>
/// <param name="y">Y轴坐标值</param>
public struct Position(float x, float y)
{ {
public float X; /// <summary>
public float Y; /// 获取X轴坐标值。
/// </summary>
public float X { get; set; } = x;
public Position(float x, float y) /// <summary>
{ /// 获取Y轴坐标值。
X = x; /// </summary>
Y = y; public float Y { get; set; } = y;
}
} }

View File

@ -1,16 +1,19 @@
namespace GFramework.Core.ecs.components; namespace GFramework.Core.ecs.components;
/// <summary> /// <summary>
/// 速度组件 /// 速度组件,用于表示实体在二维空间中的运动速度。
/// </summary> /// </summary>
public struct Velocity /// <param name="x">X轴方向的速度分量</param>
/// <param name="y">Y轴方向的速度分量</param>
public struct Velocity(float x, float y)
{ {
public float X; /// <summary>
public float Y; /// X轴方向的速度分量
/// </summary>
public float X { get; set; } = x;
public Velocity(float x, float y) /// <summary>
{ /// Y轴方向的速度分量
X = x; /// </summary>
Y = y; public float Y { get; set; } = y;
}
} }

View File

@ -1,67 +0,0 @@
using Arch.Core;
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.ecs.components;
namespace GFramework.Core.ecs.examples;
/// <summary>
/// ECS使用示例 - 演示如何创建和管理实体
/// </summary>
public static class EcsUsageExample
{
/// <summary>
/// 示例1: 创建移动的敌人实体
/// </summary>
public static void CreateMovingEnemies(IArchitectureContext context, int count)
{
var ecsWorld = context.GetEcsWorld();
var world = ecsWorld.InternalWorld;
for (int i = 0; i < count; i++)
{
// 创建实体
var entity = ecsWorld.CreateEntity(
new ComponentType[]
{
typeof(Position),
typeof(Velocity)
}
);
// 设置初始位置和速度
world.Set(entity, new Position(i * 10, 0));
var random = new Random();
world.Set(entity, new Velocity(
(float)(random.NextDouble() * 100 - 50),
(float)(random.NextDouble() * 100 - 50)
));
}
}
/// <summary>
/// 示例2: 批量清理实体
/// </summary>
public static void ClearAllEntities(IArchitectureContext context)
{
var ecsWorld = context.GetEcsWorld();
ecsWorld.Clear();
}
/// <summary>
/// 示例3: 查询特定实体
/// </summary>
public static int CountMovingEntities(IArchitectureContext context)
{
var ecsWorld = context.GetEcsWorld();
var world = ecsWorld.InternalWorld;
int count = 0;
var query = new QueryDescription()
.WithAll<Position, Velocity>();
world.Query(in query, (Entity entity) => { count++; });
return count;
}
}

View File

@ -4,14 +4,22 @@ using GFramework.Core.ecs.components;
namespace GFramework.Core.ecs.systems; namespace GFramework.Core.ecs.systems;
/// <summary> /// <summary>
/// 移动系统示例 - 根据速度更新位置 /// 移动系统,负责更新具有位置和速度组件的实体的位置。
/// 根据速度和时间增量计算实体的新位置。
/// </summary> /// </summary>
public class MovementSystem : EcsSystemBase public class MovementSystem : EcsSystemBase
{ {
private QueryDescription _query; private QueryDescription _query;
/// <summary>
/// 获取系统的优先级,数值越小优先级越高。
/// </summary>
public override int Priority => 0; public override int Priority => 0;
/// <summary>
/// ECS初始化回调方法在系统初始化时调用。
/// 创建查询描述符用于查找同时拥有Position和Velocity组件的实体。
/// </summary>
protected override void OnEcsInit() protected override void OnEcsInit()
{ {
// 创建查询查找所有同时拥有Position和Velocity组件的实体 // 创建查询查找所有同时拥有Position和Velocity组件的实体
@ -19,6 +27,10 @@ public class MovementSystem : EcsSystemBase
.WithAll<Position, Velocity>(); .WithAll<Position, Velocity>();
} }
/// <summary>
/// 系统更新方法,每帧调用一次。
/// </summary>
/// <param name="deltaTime">帧间隔时间,用于计算位置变化量</param>
public override void Update(float deltaTime) public override void Update(float deltaTime)
{ {
// 查询并更新所有符合条件的实体 // 查询并更新所有符合条件的实体

View File

@ -13,7 +13,7 @@ public abstract class AbstractModel : ContextAwareBase, IModel
/// <summary> /// <summary>
/// 初始化模型调用抽象方法OnInit执行具体初始化逻辑 /// 初始化模型调用抽象方法OnInit执行具体初始化逻辑
/// </summary> /// </summary>
void IInitializable.Init() void IInitializable.Initialize()
{ {
OnInit(); OnInit();
} }

View File

@ -48,7 +48,7 @@ public class StateMachineSystem : StateMachine, IStateMachineSystem
/// 初始化方法,在系统启动时调用 /// 初始化方法,在系统启动时调用
/// 遍历所有状态实例为实现了IContextAware接口的状态设置上下文 /// 遍历所有状态实例为实现了IContextAware接口的状态设置上下文
/// </summary> /// </summary>
public virtual void Init() public virtual void Initialize()
{ {
foreach (var state in States.Values.OfType<IContextAware>()) state.SetContext(_context); foreach (var state in States.Values.OfType<IContextAware>()) state.SetContext(_context);
} }

View File

@ -17,7 +17,7 @@ public abstract class AbstractSystem : ContextAwareBase, ISystem
/// <summary> /// <summary>
/// 系统初始化方法,调用抽象初始化方法 /// 系统初始化方法,调用抽象初始化方法
/// </summary> /// </summary>
public void Init() public void Initialize()
{ {
var name = GetType().Name; var name = GetType().Name;
_logger = LoggerFactoryResolver.Provider.CreateLogger(name); _logger = LoggerFactoryResolver.Provider.CreateLogger(name);

View File

@ -19,7 +19,7 @@ public abstract class AbstractContextUtility : ContextAwareBase, IContextUtility
/// <summary> /// <summary>
/// 初始化上下文工具类 /// 初始化上下文工具类
/// </summary> /// </summary>
public void Init() public void Initialize()
{ {
var name = GetType().Name; var name = GetType().Name;
// 获取上下文中的日志记录器 // 获取上下文中的日志记录器

View File

@ -240,7 +240,7 @@ public class SettingsModel<TRepository>(IDataLocationProvider? locationProvider,
: null; : null;
} }
// ========================= // =========================
// Init // OnInitialize
// ========================= // =========================
/// <summary> /// <summary>

View File

@ -53,7 +53,7 @@ public abstract class AbstractArchitecture(
/// 初始化架构,按顺序注册模型、系统和工具。 /// 初始化架构,按顺序注册模型、系统和工具。
/// 包括将架构绑定到Godot生命周期并调用模块安装逻辑。 /// 包括将架构绑定到Godot生命周期并调用模块安装逻辑。
/// </summary> /// </summary>
protected override void Init() protected override void OnInitialize()
{ {
_architectureAnchorName = _architectureAnchorName =
$"__{GFrameworkConstants.FrameworkName}__{GetType().Name}__{GetHashCode()}__ArchitectureAnchor__"; $"__{GFrameworkConstants.FrameworkName}__{GetType().Name}__{GetHashCode()}__ArchitectureAnchor__";
@ -76,7 +76,7 @@ public abstract class AbstractArchitecture(
if (Engine.GetMainLoop() is not SceneTree tree) if (Engine.GetMainLoop() is not SceneTree tree)
return; return;
// 防止重复挂载(热重载 / 多次 Init // 防止重复挂载(热重载 / 多次 OnInitialize
if (tree.Root.GetNodeOrNull(_architectureAnchorName) != null) if (tree.Root.GetNodeOrNull(_architectureAnchorName) != null)
return; return;