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 提供
|
||||
/// </summary>
|
||||
public interface IArchitecture : IAsyncInitializable
|
||||
public interface IArchitecture : IAsyncInitializable, IAsyncDestroyable, IInitializable, IDestroyable
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取架构上下文
|
||||
@ -25,22 +25,6 @@ public interface IArchitecture : IAsyncInitializable
|
||||
/// </value>
|
||||
Action<IServiceCollection>? Configurator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法,用于执行对象的初始化操作
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该方法通常用于设置初始状态、初始化成员变量或执行必要的预处理操作
|
||||
/// </remarks>
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// 销毁方法,用于执行对象的清理和销毁操作
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该方法通常用于释放资源、清理内存或执行必要的清理操作
|
||||
/// </remarks>
|
||||
void Destroy();
|
||||
|
||||
/// <summary>
|
||||
/// 注册系统实例到架构中
|
||||
/// </summary>
|
||||
|
||||
@ -8,5 +8,5 @@ public interface IInitializable
|
||||
/// <summary>
|
||||
/// 初始化组件
|
||||
/// </summary>
|
||||
void Init();
|
||||
void Initialize();
|
||||
}
|
||||
@ -321,7 +321,7 @@ public class TestSystemV2 : ISystem
|
||||
return _context;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
@ -349,7 +349,7 @@ public class TestModelV2 : IModel
|
||||
return _context;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -11,12 +11,12 @@ public class AsyncTestArchitecture : TestArchitectureBase
|
||||
/// <summary>
|
||||
/// 异步初始化架构
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
// 注册模型
|
||||
RegisterModel(new AsyncTestModel());
|
||||
// 注册系统
|
||||
RegisterSystem(new AsyncTestSystem());
|
||||
base.Init();
|
||||
base.OnInitialize();
|
||||
}
|
||||
}
|
||||
@ -222,7 +222,7 @@ public class TestArchitecture : Architecture
|
||||
/// <summary>
|
||||
/// 初始化方法,当前为空实现
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,10 +11,10 @@ public sealed class SyncTestArchitecture : TestArchitectureBase
|
||||
/// <summary>
|
||||
/// 初始化架构组件,注册模型、系统并设置事件监听器
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
RegisterModel(new TestModel());
|
||||
RegisterSystem(new TestSystem());
|
||||
base.Init();
|
||||
base.OnInitialize();
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@ public abstract class TestArchitectureBase : Architecture
|
||||
/// <summary>
|
||||
/// 初始化架构组件,注册模型、系统并设置事件监听器
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
InitCalled = true;
|
||||
_postRegistrationHook?.Invoke(this);
|
||||
|
||||
@ -53,7 +53,7 @@ public class EcsAdvancedTests
|
||||
{
|
||||
var system = (IEcsSystem)Activator.CreateInstance(systemType)!;
|
||||
((IContextAware)system).SetContext(_context!);
|
||||
system.Init();
|
||||
system.Initialize();
|
||||
systems.Add(system);
|
||||
_container.RegisterPlurality(system);
|
||||
}
|
||||
@ -65,7 +65,7 @@ public class EcsAdvancedTests
|
||||
{
|
||||
var runner = new EcsSystemRunner();
|
||||
((IContextAware)runner).SetContext(_context!);
|
||||
runner.Init();
|
||||
runner.Initialize();
|
||||
return runner;
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ public class EcsAdvancedTests
|
||||
foreach (var system in new[] { systemA, systemB, systemC })
|
||||
{
|
||||
((IContextAware)system).SetContext(_context!);
|
||||
system.Init();
|
||||
system.Initialize();
|
||||
_container.RegisterPlurality(system);
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ public class EcsAdvancedTests
|
||||
|
||||
var movementSystem = new MovementSystem();
|
||||
((IContextAware)movementSystem).SetContext(_context!);
|
||||
movementSystem.Init();
|
||||
movementSystem.Initialize();
|
||||
_container.RegisterPlurality(movementSystem);
|
||||
|
||||
_container.Register(new List<IEcsSystem> { movementSystem } as IReadOnlyList<IEcsSystem>);
|
||||
|
||||
@ -68,7 +68,7 @@ public class EcsBasicTests
|
||||
{
|
||||
var system = (IEcsSystem)Activator.CreateInstance(systemType)!;
|
||||
system.SetContext(_context!);
|
||||
system.Init();
|
||||
system.Initialize();
|
||||
systems.Add(system);
|
||||
_container.RegisterPlurality(system);
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public class EcsIntegrationTests
|
||||
{
|
||||
var system = (IEcsSystem)Activator.CreateInstance(systemType)!;
|
||||
system.SetContext(_context!);
|
||||
system.Init();
|
||||
system.Initialize();
|
||||
systems.Add(system);
|
||||
_container.RegisterPlurality(system);
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class MediatorComprehensiveTests
|
||||
var results = new List<int>();
|
||||
|
||||
// 流应该在100ms后被取消(TaskCanceledException 继承自 OperationCanceledException)
|
||||
Assert.ThrowsAsync<OperationCanceledException>(async () =>
|
||||
Assert.CatchAsync<OperationCanceledException>(async () =>
|
||||
{
|
||||
await foreach (var item in stream)
|
||||
{
|
||||
|
||||
@ -30,8 +30,8 @@ public sealed class AsyncTestModel : AbstractModel, IAsyncInitializable
|
||||
/// <exception cref="InvalidOperationException">当该方法被调用时抛出异常</exception>
|
||||
public void Init()
|
||||
{
|
||||
// sync Init 不应该被调用
|
||||
throw new InvalidOperationException("Sync Init should not be called");
|
||||
// sync OnInitialize 不应该被调用
|
||||
throw new InvalidOperationException("Sync OnInitialize should not be called");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -15,7 +15,7 @@ public sealed class FailingModel : IModel
|
||||
/// 该方法会故意抛出InvalidOperationException异常
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">总是抛出此异常以模拟初始化失败</exception>
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
throw new InvalidOperationException("Model init failed intentionally");
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ public sealed class TestModel : AbstractModel, ITestModel
|
||||
/// <summary>
|
||||
/// 初始化模型
|
||||
/// </summary>
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ public class StateMachineSystemTests
|
||||
Assert.Throws<InvalidOperationException>(() => state1.GetContext());
|
||||
Assert.Throws<InvalidOperationException>(() => state2.GetContext());
|
||||
|
||||
_stateMachine.Init();
|
||||
_stateMachine.Initialize();
|
||||
|
||||
Assert.That(state1.GetContext(), Is.SameAs(_context));
|
||||
Assert.That(state2.GetContext(), Is.SameAs(_context));
|
||||
@ -129,7 +129,7 @@ public class StateMachineSystemTests
|
||||
var state = new TestStateV5();
|
||||
|
||||
_stateMachine!.Register(state);
|
||||
_stateMachine.Init();
|
||||
_stateMachine.Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -173,7 +173,7 @@ public class StateMachineSystemTests
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
_stateMachine.Init();
|
||||
_stateMachine.Initialize();
|
||||
await _stateMachine.ChangeToAsync<TestStateV5>();
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
@ -203,7 +203,7 @@ public class StateMachineSystemTests
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
_stateMachine.Init();
|
||||
_stateMachine.Initialize();
|
||||
await _stateMachine.ChangeToAsync<TestStateV5>();
|
||||
|
||||
eventReceived = false;
|
||||
@ -230,7 +230,7 @@ public class StateMachineSystemTests
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
_stateMachine.Init();
|
||||
_stateMachine.Initialize();
|
||||
await _stateMachine.ChangeToAsync<TestStateV5>();
|
||||
await _stateMachine.ChangeToAsync<TestStateV5_2>();
|
||||
await _stateMachine.ChangeToAsync<TestStateV5>();
|
||||
|
||||
@ -30,10 +30,10 @@ public sealed class AsyncTestSystem : ISystem, IAsyncInitializable
|
||||
return _context;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
// 同步 Init 不应该被调用
|
||||
throw new InvalidOperationException("Sync Init should not be called");
|
||||
// 同步 OnInitialize 不应该被调用
|
||||
throw new InvalidOperationException("Sync OnInitialize should not be called");
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
|
||||
@ -45,7 +45,7 @@ public sealed class TestSystem : ISystem
|
||||
/// <summary>
|
||||
/// 初始化系统
|
||||
/// </summary>
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
@ -61,11 +61,11 @@ public class AbstractContextUtilityTests
|
||||
{
|
||||
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>
|
||||
@ -76,11 +76,11 @@ public class AbstractContextUtilityTests
|
||||
{
|
||||
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>
|
||||
@ -91,11 +91,11 @@ public class AbstractContextUtilityTests
|
||||
{
|
||||
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>
|
||||
@ -106,7 +106,7 @@ public class AbstractContextUtilityTests
|
||||
{
|
||||
var utility = new TestContextUtilityV1();
|
||||
|
||||
utility.Init();
|
||||
utility.Initialize();
|
||||
Assert.That(utility.Destroyed, Is.False, "Utility should not be destroyed before Destroy");
|
||||
|
||||
utility.Destroy();
|
||||
@ -156,7 +156,7 @@ public class AbstractContextUtilityTests
|
||||
Assert.That(utility.Initialized, Is.False);
|
||||
Assert.That(utility.CustomInitializationDone, Is.False);
|
||||
|
||||
utility.Init();
|
||||
utility.Initialize();
|
||||
|
||||
Assert.That(utility.Initialized, Is.True);
|
||||
Assert.That(utility.CustomInitializationDone, Is.True);
|
||||
@ -175,7 +175,7 @@ public class AbstractContextUtilityTests
|
||||
Assert.That(utility.Destroyed, Is.False);
|
||||
|
||||
// 初始化
|
||||
utility.Init();
|
||||
utility.Initialize();
|
||||
Assert.That(utility.Initialized, Is.True);
|
||||
Assert.That(utility.Destroyed, Is.False);
|
||||
|
||||
@ -194,7 +194,7 @@ public class AbstractContextUtilityTests
|
||||
var utility = new TestContextUtilityV1();
|
||||
|
||||
// 第一次初始化和销毁
|
||||
utility.Init();
|
||||
utility.Initialize();
|
||||
Assert.That(utility.Initialized, Is.True);
|
||||
utility.Destroy();
|
||||
Assert.That(utility.Destroyed, Is.True);
|
||||
@ -203,7 +203,7 @@ public class AbstractContextUtilityTests
|
||||
utility.Destroyed = false;
|
||||
|
||||
// 第二次初始化和销毁
|
||||
utility.Init();
|
||||
utility.Initialize();
|
||||
Assert.That(utility.Initialized, Is.True);
|
||||
utility.Destroy();
|
||||
Assert.That(utility.Destroyed, Is.True);
|
||||
|
||||
@ -261,15 +261,11 @@ public abstract class Architecture(
|
||||
}
|
||||
|
||||
// 处理销毁(支持 IDestroyable 或 IAsyncDestroyable)
|
||||
if (component is IDestroyable or IAsyncDestroyable)
|
||||
{
|
||||
// 原子去重:HashSet.Add 返回 true 表示添加成功(之前不存在)
|
||||
if (_disposableSet.Add(component))
|
||||
{
|
||||
_disposables.Add(component);
|
||||
_logger.Trace($"Registered {component.GetType().Name} for destruction");
|
||||
}
|
||||
}
|
||||
if (component is not (IDestroyable or IAsyncDestroyable)) return;
|
||||
// 原子去重:HashSet.Add 返回 true 表示添加成功(之前不存在)
|
||||
if (!_disposableSet.Add(component)) return;
|
||||
_disposables.Add(component);
|
||||
_logger.Trace($"Registered {component.GetType().Name} for destruction");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -354,13 +350,13 @@ public abstract class Architecture(
|
||||
if (asyncMode && component is IAsyncInitializable asyncInit)
|
||||
await asyncInit.InitializeAsync();
|
||||
else
|
||||
component.Init();
|
||||
component.Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抽象初始化方法,由子类重写以进行自定义初始化操作
|
||||
/// </summary>
|
||||
protected abstract void Init();
|
||||
protected abstract void OnInitialize();
|
||||
|
||||
/// <summary>
|
||||
/// 异步销毁架构及所有组件
|
||||
@ -663,10 +659,10 @@ public abstract class Architecture(
|
||||
|
||||
// 执行服务钩子
|
||||
Container.ExecuteServicesHook(Configurator);
|
||||
// === 用户 Init ===
|
||||
_logger.Debug("Calling user Init()");
|
||||
Init();
|
||||
_logger.Debug("User Init() completed");
|
||||
// === 用户 OnInitialize ===
|
||||
_logger.Debug("Calling user OnInitialize()");
|
||||
OnInitialize();
|
||||
_logger.Debug("User OnInitialize() completed");
|
||||
|
||||
// === 组件初始化阶段 ===
|
||||
await InitializeAllComponentsAsync(asyncMode);
|
||||
|
||||
@ -90,7 +90,7 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
|
||||
var mediator = Mediator;
|
||||
if (mediator == null)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Arch.Core;
|
||||
using GFramework.Core.Abstractions.ecs;
|
||||
using GFramework.Core.extensions;
|
||||
using GFramework.Core.system;
|
||||
|
||||
namespace GFramework.Core.ecs;
|
||||
@ -34,7 +35,7 @@ public abstract class EcsSystemBase : AbstractSystem, IEcsSystem
|
||||
/// </summary>
|
||||
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.");
|
||||
|
||||
OnEcsInit();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using GFramework.Core.Abstractions.ecs;
|
||||
using GFramework.Core.extensions;
|
||||
using GFramework.Core.system;
|
||||
|
||||
namespace GFramework.Core.ecs;
|
||||
@ -17,8 +18,8 @@ public sealed class EcsSystemRunner : AbstractSystem
|
||||
protected override void OnInit()
|
||||
{
|
||||
// 从容器获取所有已注册的ECS系统
|
||||
var systemsList = Context.GetService<IReadOnlyList<IEcsSystem>>();
|
||||
if (systemsList != null && systemsList.Count > 0)
|
||||
var systemsList = this.GetService<IReadOnlyList<IEcsSystem>>();
|
||||
if (systemsList is { Count: > 0 })
|
||||
{
|
||||
// 按优先级排序
|
||||
_systems.AddRange(systemsList.OrderBy(s => s.Priority));
|
||||
|
||||
@ -8,25 +8,24 @@ namespace GFramework.Core.ecs;
|
||||
/// </summary>
|
||||
public sealed class EcsWorld : IEcsWorld
|
||||
{
|
||||
private readonly World _world = World.Create();
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// 获取内部的Arch World实例
|
||||
/// </summary>
|
||||
public World InternalWorld => _world;
|
||||
public World InternalWorld { get; } = World.Create();
|
||||
|
||||
/// <summary>
|
||||
/// 当前实体数量
|
||||
/// </summary>
|
||||
public int EntityCount => _world.Size;
|
||||
public int EntityCount => InternalWorld.Size;
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新实体
|
||||
/// </summary>
|
||||
public Entity CreateEntity(params ComponentType[] types)
|
||||
{
|
||||
return _world.Create(types);
|
||||
return InternalWorld.Create(types);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -34,7 +33,7 @@ public sealed class EcsWorld : IEcsWorld
|
||||
/// </summary>
|
||||
public void DestroyEntity(Entity entity)
|
||||
{
|
||||
_world.Destroy(entity);
|
||||
InternalWorld.Destroy(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -42,7 +41,7 @@ public sealed class EcsWorld : IEcsWorld
|
||||
/// </summary>
|
||||
public bool IsAlive(Entity entity)
|
||||
{
|
||||
return _world.IsAlive(entity);
|
||||
return InternalWorld.IsAlive(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -50,7 +49,7 @@ public sealed class EcsWorld : IEcsWorld
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_world.Clear();
|
||||
InternalWorld.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -60,7 +59,7 @@ public sealed class EcsWorld : IEcsWorld
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
World.Destroy(_world);
|
||||
World.Destroy(InternalWorld);
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,19 @@
|
||||
namespace GFramework.Core.ecs.components;
|
||||
|
||||
/// <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;
|
||||
public float Y;
|
||||
/// <summary>
|
||||
/// 获取X轴坐标值。
|
||||
/// </summary>
|
||||
public float X { get; set; } = x;
|
||||
|
||||
public Position(float x, float y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取Y轴坐标值。
|
||||
/// </summary>
|
||||
public float Y { get; set; } = y;
|
||||
}
|
||||
@ -1,16 +1,19 @@
|
||||
namespace GFramework.Core.ecs.components;
|
||||
|
||||
/// <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;
|
||||
public float Y;
|
||||
/// <summary>
|
||||
/// X轴方向的速度分量
|
||||
/// </summary>
|
||||
public float X { get; set; } = x;
|
||||
|
||||
public Velocity(float x, float y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
/// <summary>
|
||||
/// Y轴方向的速度分量
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// 移动系统示例 - 根据速度更新位置
|
||||
/// 移动系统,负责更新具有位置和速度组件的实体的位置。
|
||||
/// 根据速度和时间增量计算实体的新位置。
|
||||
/// </summary>
|
||||
public class MovementSystem : EcsSystemBase
|
||||
{
|
||||
private QueryDescription _query;
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统的优先级,数值越小优先级越高。
|
||||
/// </summary>
|
||||
public override int Priority => 0;
|
||||
|
||||
/// <summary>
|
||||
/// ECS初始化回调方法,在系统初始化时调用。
|
||||
/// 创建查询描述符,用于查找同时拥有Position和Velocity组件的实体。
|
||||
/// </summary>
|
||||
protected override void OnEcsInit()
|
||||
{
|
||||
// 创建查询:查找所有同时拥有Position和Velocity组件的实体
|
||||
@ -19,6 +27,10 @@ public class MovementSystem : EcsSystemBase
|
||||
.WithAll<Position, Velocity>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统更新方法,每帧调用一次。
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">帧间隔时间,用于计算位置变化量</param>
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
// 查询并更新所有符合条件的实体
|
||||
|
||||
@ -13,7 +13,7 @@ public abstract class AbstractModel : ContextAwareBase, IModel
|
||||
/// <summary>
|
||||
/// 初始化模型,调用抽象方法OnInit执行具体初始化逻辑
|
||||
/// </summary>
|
||||
void IInitializable.Init()
|
||||
void IInitializable.Initialize()
|
||||
{
|
||||
OnInit();
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ public class StateMachineSystem : StateMachine, IStateMachineSystem
|
||||
/// 初始化方法,在系统启动时调用
|
||||
/// 遍历所有状态实例,为实现了IContextAware接口的状态设置上下文
|
||||
/// </summary>
|
||||
public virtual void Init()
|
||||
public virtual void Initialize()
|
||||
{
|
||||
foreach (var state in States.Values.OfType<IContextAware>()) state.SetContext(_context);
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ public abstract class AbstractSystem : ContextAwareBase, ISystem
|
||||
/// <summary>
|
||||
/// 系统初始化方法,调用抽象初始化方法
|
||||
/// </summary>
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
var name = GetType().Name;
|
||||
_logger = LoggerFactoryResolver.Provider.CreateLogger(name);
|
||||
|
||||
@ -19,7 +19,7 @@ public abstract class AbstractContextUtility : ContextAwareBase, IContextUtility
|
||||
/// <summary>
|
||||
/// 初始化上下文工具类
|
||||
/// </summary>
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
var name = GetType().Name;
|
||||
// 获取上下文中的日志记录器
|
||||
|
||||
@ -240,7 +240,7 @@ public class SettingsModel<TRepository>(IDataLocationProvider? locationProvider,
|
||||
: null;
|
||||
}
|
||||
// =========================
|
||||
// Init
|
||||
// OnInitialize
|
||||
// =========================
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -53,7 +53,7 @@ public abstract class AbstractArchitecture(
|
||||
/// 初始化架构,按顺序注册模型、系统和工具。
|
||||
/// 包括将架构绑定到Godot生命周期并调用模块安装逻辑。
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
_architectureAnchorName =
|
||||
$"__{GFrameworkConstants.FrameworkName}__{GetType().Name}__{GetHashCode()}__ArchitectureAnchor__";
|
||||
@ -76,7 +76,7 @@ public abstract class AbstractArchitecture(
|
||||
if (Engine.GetMainLoop() is not SceneTree tree)
|
||||
return;
|
||||
|
||||
// 防止重复挂载(热重载 / 多次 Init)
|
||||
// 防止重复挂载(热重载 / 多次 OnInitialize)
|
||||
if (tree.Root.GetNodeOrNull(_architectureAnchorName) != null)
|
||||
return;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user