iFactory.Godot/BITKit/Scripts/ECS/Core/Entity.cs

178 lines
4.2 KiB
C#
Raw Normal View History

2023-06-12 15:51:41 +08:00
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
2023-09-15 23:02:46 +08:00
using System.Reflection;
2023-09-20 11:38:30 +08:00
using System.Threading;
2023-11-02 20:58:36 +08:00
using BITKit.Entities;
2023-09-15 23:02:46 +08:00
using Microsoft.Extensions.DependencyInjection;
2023-09-20 11:38:30 +08:00
using Microsoft.Extensions.Logging;
2023-09-15 23:02:46 +08:00
2023-06-12 15:51:41 +08:00
namespace BITKit;
/// <summary>
/// 用于Godot的ECS.Entity实现
/// </summary>
public partial class Entity : Node,IEntity
{
/// <summary>
/// 类型组件的缓存
/// </summary>
2023-09-15 23:02:46 +08:00
private readonly Dictionary<Type,object> TypeComponents=new ();
2023-11-02 20:58:36 +08:00
private Object[] Components = Array.Empty<Object>();
2023-06-12 15:51:41 +08:00
/// <summary>
/// IEntityService的缓存
/// </summary>
private IEntitiesService _entitiesService;
/// <summary>
/// 所有EntityComponent
/// </summary>
2023-11-02 20:58:36 +08:00
IEntityComponent[] IEntity.Components => Components.OfType<IEntityComponent>().ToArray();
2024-04-16 04:15:21 +08:00
public void WaitForInitializationComplete()
{
throw new NotImplementedException();
}
2023-06-12 15:51:41 +08:00
/// <summary>
/// IEntity.Id实现
/// </summary>
public ulong Id { get; private set; }
2023-09-20 11:38:30 +08:00
public CancellationToken CancellationToken => _cancellationTokenSource.Token;
private CancellationTokenSource _cancellationTokenSource;
2023-06-12 15:51:41 +08:00
/// <summary>
2023-09-15 23:02:46 +08:00
/// 服务提供者
/// </summary>
public IServiceProvider ServiceProvider { get; private set; }
2023-11-02 20:58:36 +08:00
/// <summary>
/// 服务集合
/// </summary>
public IServiceCollection ServiceCollection { get; private set; }
2023-10-19 14:33:06 +08:00
2023-11-02 20:58:36 +08:00
public void Inject(object node)
2023-10-19 14:33:06 +08:00
{
2023-11-02 20:58:36 +08:00
foreach (var fieldInfo in node.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x=>x.GetCustomAttribute<InjectAttribute>() is not null)
)
{
var attribute = fieldInfo.GetCustomAttribute<InjectAttribute>();
if(attribute is null)continue;
fieldInfo.SetValue(node,
attribute.CanBeNull
? ServiceProvider.GetService(fieldInfo.FieldType)
: ServiceProvider.GetRequiredService(fieldInfo.FieldType));
}
2023-10-19 14:33:06 +08:00
}
2023-09-20 11:38:30 +08:00
public override void _EnterTree()
{
_cancellationTokenSource = new CancellationTokenSource();
}
public override void _ExitTree()
{
_cancellationTokenSource.Cancel();
2023-11-02 20:58:36 +08:00
DI.Get<IEntitiesService>().UnRegister(this);
2023-09-20 11:38:30 +08:00
}
2023-09-15 23:02:46 +08:00
/// <summary>
2023-06-12 15:51:41 +08:00
/// 加载所有EntityComponent的内部实现
/// </summary>
public override void _Ready()
{
Id = GetInstanceId();
2023-09-15 23:02:46 +08:00
2023-11-02 20:58:36 +08:00
ServiceCollection = new ServiceCollection();
2023-09-15 23:02:46 +08:00
2023-11-02 20:58:36 +08:00
DI.Get<IEntitiesService>().Register(this);
Components = MathNode.GetAllNode(this).ToArray();
List<IEntityComponent> entityComponents = new();
_entitiesService = DI.Get<IEntitiesService>();
foreach (var x in Components)
2023-06-12 15:51:41 +08:00
{
GetInstanceId();
2023-11-02 20:58:36 +08:00
2023-09-15 23:02:46 +08:00
if (x is IEntityComponent entityComponent)
{
2023-11-02 20:58:36 +08:00
entityComponent.BuildService(ServiceCollection);
2023-09-15 23:02:46 +08:00
}
2023-11-02 20:58:36 +08:00
TypeComponents.TryAdd(x.GetType(), x);
2023-09-15 23:02:46 +08:00
foreach (var customType in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
{
2023-11-02 20:58:36 +08:00
TypeComponents.TryAdd(customType.Type, x);
ServiceCollection.AddSingleton(customType.Type, x);
2023-09-15 23:02:46 +08:00
}
2023-11-02 20:58:36 +08:00
ServiceProvider = ServiceCollection.BuildServiceProvider();
2023-09-15 23:02:46 +08:00
2023-06-12 15:51:41 +08:00
if (x is not IEntityComponent component) continue;
component.Entity = this;
entityComponents.Add(component);
}
2023-11-02 20:58:36 +08:00
foreach (var node in Components)
{
Inject(node);
}
foreach (var component in Components.OfType<IEntityBehavior>())
{
component.Initialize(this);
}
foreach (var component in Components.OfType<IEntityBehavior>())
{
component.OnAwake();
}
foreach (var component in Components.OfType<IEntityBehavior>())
2023-06-12 15:51:41 +08:00
{
component.OnStart();
}
}
2023-09-21 03:49:27 +08:00
2023-11-02 20:58:36 +08:00
public override void _Process(double delta)
{
foreach (var component in Components.OfType<IEntityBehavior>())
{
component.OnUpdate((float)delta);
}
foreach (var component in Components.OfType<IEntityBehavior>())
{
component.OnLateUpdate((float)delta);
}
}
public override void _PhysicsProcess(double delta)
{
foreach (var component in Components.OfType<IEntityBehavior>())
{
component.OnFixedUpdate((float)delta);
}
}
2023-09-21 03:49:27 +08:00
2023-09-15 23:02:46 +08:00
public bool TryGetComponent<T>(out T component)
2023-06-12 15:51:41 +08:00
{
if (TypeComponents.TryGetValue(typeof(T), out var iComponent) && iComponent is T _component)
{
component = _component;
return true;
}
component = default;
return false;
}
2023-09-15 23:02:46 +08:00
public bool RegisterComponent<T>(T component)
2023-06-12 15:51:41 +08:00
{
return TypeComponents.TryAdd(typeof(T), component);
}
2023-09-15 23:02:46 +08:00
2023-06-12 15:51:41 +08:00
}