mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(architecture): 重构架构初始化和销毁机制
- 将Init方法统一重命名为Initialize方法以提高一致性 - 修改Architecture类中的组件注册逻辑,优化去重判断 - 更新ECS系统基础类以使用新的初始化接口 - 重构EcsWorld类使用属性自动实现而非私有字段 - 移除过时的EcsUsageExample示例文件 - 更新相关测试类以匹配新的初始化方法命名 - 改进代码注释和文档字符串格式
This commit is contained in:
parent
35845be93f
commit
3db89ab498
@ -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>
|
||||||
|
|||||||
@ -8,5 +8,5 @@ public interface IInitializable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化组件
|
/// 初始化组件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Init();
|
void Initialize();
|
||||||
}
|
}
|
||||||
@ -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()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,7 +222,7 @@ public class TestArchitecture : Architecture
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化方法,当前为空实现
|
/// 初始化方法,当前为空实现
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void Init()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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>);
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ public sealed class TestModel : AbstractModel, ITestModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化模型
|
/// 初始化模型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Init()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>();
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public sealed class TestSystem : ISystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化系统
|
/// 初始化系统
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Init()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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)
|
||||||
{
|
{
|
||||||
// 查询并更新所有符合条件的实体
|
// 查询并更新所有符合条件的实体
|
||||||
|
|||||||
@ -13,7 +13,7 @@ public abstract class AbstractModel : ContextAwareBase, IModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化模型,调用抽象方法OnInit执行具体初始化逻辑
|
/// 初始化模型,调用抽象方法OnInit执行具体初始化逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void IInitializable.Init()
|
void IInitializable.Initialize()
|
||||||
{
|
{
|
||||||
OnInit();
|
OnInit();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
// 获取上下文中的日志记录器
|
// 获取上下文中的日志记录器
|
||||||
|
|||||||
@ -240,7 +240,7 @@ public class SettingsModel<TRepository>(IDataLocationProvider? locationProvider,
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
// =========================
|
// =========================
|
||||||
// Init
|
// OnInitialize
|
||||||
// =========================
|
// =========================
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user