Net.Like.Xue.Tokyo/Assets/BITKit/Core/ECS/UnityEntity.cs

155 lines
4.3 KiB
C#
Raw Normal View History

2025-05-06 16:10:12 +08:00
using BITKit;
#if UNITY_EDITOR
using BITKit.Entities;
using UnityEditor;
using UnityEngine.UIElements;
#endif
2025-03-03 18:44:00 +08:00
#if UNITY_5_3_OR_NEWER
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
2025-05-06 16:10:12 +08:00
2025-03-03 18:44:00 +08:00
using UnityEngine;
using Object = UnityEngine.Object;
namespace BITKit.Entities
{
[DisallowMultipleComponent]
[DefaultExecutionOrder(-1)]
public class UnityEntity : MonoBehaviour,IEntity
{
2025-03-15 20:09:18 +08:00
[SerializeField] private bool debug;
2025-03-03 18:44:00 +08:00
private IEntitiesService _entitiesService;
private IEntity _entity;
private void Start()
{
_entitiesService = BITApp.ServiceProvider.GetRequiredService<IEntitiesService>();
if (_entitiesService.Entities.ContainsKey(gameObject.GetInstanceID())) return;
2025-03-15 20:09:18 +08:00
if (debug)
{
}
2025-03-03 18:44:00 +08:00
var entity = new Entity()
{
Id = gameObject.GetInstanceID(),
CancellationToken = destroyCancellationToken
};
var idComponent = new IdComponent()
{
Id = entity.Id,
Name = gameObject.name,
};
entity.ServiceCollection.AddSingleton(idComponent);
foreach (var component in GetComponents<Component>())
{
2025-03-12 22:46:37 +08:00
if(!component)continue;
2025-03-03 18:44:00 +08:00
var type = component.GetType();
2025-03-15 20:09:18 +08:00
entity.ServiceCollection.AddSingleton(type, component);
2025-03-03 18:44:00 +08:00
foreach (var x in type.GetInterfaces())
{
entity.ServiceCollection.AddSingleton(x, component);
}
while (type is not null)
{
var baseType = type.BaseType;
try
{
switch (baseType)
{
case null:
case not null when baseType == typeof(object):
case not null when baseType == typeof(Object):
case not null when baseType == typeof(MonoBehaviour):
case not null when baseType == typeof(Behaviour):
case not null when baseType == typeof(Component):
case not null when baseType == typeof(Component):
throw new OperationCanceledException();
}
}
catch (OperationCanceledException)
{
break;
}
entity.ServiceCollection.AddSingleton(baseType, component);
type = type.BaseType;
}
}
entity.ServiceCollection.AddSingleton(gameObject);
entity.ServiceCollection.AddSingleton(transform);
destroyCancellationToken.Register(Dispose);
_entity = entity;
_entitiesService.Register(entity);
}
private void Dispose()
{
_entitiesService?.UnRegister(_entity);
}
public int Id => _entity.Id;
public CancellationToken CancellationToken => _entity.CancellationToken;
public IServiceProvider ServiceProvider => _entity.ServiceProvider;
public IServiceCollection ServiceCollection => _entity.ServiceCollection;
public void Inject(object obj)
{
_entity.Inject(obj);
}
}
}
2025-05-06 16:10:12 +08:00
#endif
#if UNITY_EDITOR
public class UnityEntitiesWindow:EditorWindow
{
[MenuItem("Tools/Entities/Editor Window")]
private static void Open()
{
GetWindow<UnityEntitiesWindow>().Show();
}
private Label _hint;
private VisualElement _container;
private void OnEnable()
{
var scrollView = rootVisualElement.Create<ScrollView>();
_hint = scrollView.Create<Label>();
_container = scrollView.Create<VisualElement>();
}
private void OnInspectorUpdate()
{
if(BITApp.ServiceProvider is null || BITApp.ServiceProvider.QueryComponents(out IEntitiesService entitiesService) is false)return;
_hint.text = $"Entities Count: {entitiesService.Entities.Count}";
}
}
2025-03-03 18:44:00 +08:00
#endif