using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BITKit.Core.Entites;
using Microsoft.Extensions.DependencyInjection;
namespace BITKit;
///
/// 用于Godot的ECS.Entity实现
///
public partial class Entity : Node,IEntity
{
///
/// 类型组件的缓存
///
private readonly Dictionary TypeComponents=new ();
///
/// IEntityService的缓存
///
private IEntitiesService _entitiesService;
///
/// 所有EntityComponent
///
private IEntityComponent[] _components;
IEntityComponent[] IEntity.Components => _components;
///
/// IEntity.Id实现
///
public ulong Id { get; private set; }
///
/// 服务提供者
///
public IServiceProvider ServiceProvider { get; private set; }
private IServiceCollection _serviceCollection;
///
/// 加载所有EntityComponent的内部实现
///
public override void _Ready()
{
List entityComponents = new();
Id = GetInstanceId();
_entitiesService = DI.Get();
_serviceCollection = new ServiceCollection();
_serviceCollection.AddLogging();
foreach (var x in MathNode.GetAllNode(this))
{
GetInstanceId();
if (x is IEntityComponent entityComponent)
{
entityComponent.BuildService(_serviceCollection);
}
foreach (var customType in x.GetType().GetCustomAttributes())
{
_serviceCollection.AddSingleton(customType.Type,x);
}
ServiceProvider = _serviceCollection.BuildServiceProvider();
if (x is not IEntityComponent component) continue;
component.Entity = this;
TypeComponents.TryAdd(component.BaseType,component);
//BIT4Log.Log($"已加载组件:{x.Name}");
component.OnAwake();
entityComponents.Add(component);
}
foreach (var component in TypeComponents.Values.OfType())
{
component.OnStart();
}
_entitiesService.Register(this);
this._components = entityComponents.ToArray();
SetMeta("Components",Variant.From(_components.Select(x=>x.GetType().Name).ToArray()));
}
public bool TryGetComponent(out T component)
{
if (TypeComponents.TryGetValue(typeof(T), out var iComponent) && iComponent is T _component)
{
component = _component;
return true;
}
component = default;
return false;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_entitiesService.UnRegister(this);
}
}
public bool RegisterComponent(T component)
{
return TypeComponents.TryAdd(typeof(T), component);
}
}