169 lines
6.6 KiB
C#
169 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using BITKit.Core.Entites;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine.UIElements;
|
|
// ReSharper disable RedundantTypeArgumentsOfMethod
|
|
|
|
namespace BITKit.Entities
|
|
{
|
|
public class Entity : MonoBehaviour, IEntity
|
|
{
|
|
private readonly GenericEvent genericEvent = new();
|
|
private readonly Processor processor = new();
|
|
public IEntityComponent[] entityComponents { get; set; }
|
|
public ulong Id { get; private set; }
|
|
public CancellationToken CancellationToken => _cancellationToken;
|
|
|
|
Core.Entites.IEntityComponent[] Core.Entites.IEntity.Components => _components;
|
|
|
|
bool Core.Entites.IEntity.RegisterComponent<T>(T component)
|
|
{
|
|
throw new InvalidOperationException("Unity Entity can't register component");
|
|
}
|
|
|
|
IServiceProvider Core.Entites.IEntity.ServiceProvider=> throw new InvalidOperationException("Unity Entity can't register component");
|
|
|
|
private CancellationToken _cancellationToken;
|
|
private bool isInitialized;
|
|
private Core.Entites.IEntityComponent[] _components => entityComponents;
|
|
|
|
private void Awake()
|
|
{
|
|
Id = (ulong)Guid.NewGuid().GetHashCode();
|
|
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
|
Set(_cancellationToken);
|
|
entityComponents = GetComponentsInChildren<IEntityComponent>(true).Distinct().ToArray();
|
|
|
|
UnityEntitiesService.Register(this);
|
|
}
|
|
private void Start()
|
|
{
|
|
foreach (var x in entityComponents)
|
|
{
|
|
foreach (var att in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
|
|
{
|
|
genericEvent.Set(att.Type,x);
|
|
genericEvent.Set(att.Type.FullName, x);
|
|
genericEvent.SetDirect(att.Type.FullName,x);
|
|
}
|
|
}
|
|
foreach (var x in GetComponentsInChildren<MonoBehaviour>(true))
|
|
{
|
|
foreach (var fieldInfo in x
|
|
.GetType()
|
|
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
|
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>() is not null))
|
|
{
|
|
var type = fieldInfo.FieldType;
|
|
if(genericEvent.TryGetObjectDirect(type.FullName,out var value))
|
|
{
|
|
fieldInfo.SetValue(x,value);
|
|
}
|
|
else
|
|
{
|
|
BIT4Log.Warning<Entity>($"{name}未找到{type.FullName}");
|
|
BIT4Log.Warning<Entity>(genericEvent.GetDiagnostics());
|
|
}
|
|
}
|
|
}
|
|
entityComponents.ForEach(x => x.Initialize(this));
|
|
|
|
entityComponents.ForEach(x => x.OnAwake());
|
|
entityComponents.ForEach(x => x.OnStart());
|
|
isInitialized = true;
|
|
}
|
|
private void OnDestroy()
|
|
{
|
|
if (isInitialized)
|
|
{
|
|
entityComponents.ForEach(x => x.OnDestroyComponent());
|
|
}
|
|
UnityEntitiesService.UnRegister(this);
|
|
}
|
|
private void Update()
|
|
{
|
|
entityComponents.ForEach(x => x.OnUpdate(Time.deltaTime));
|
|
}
|
|
private void FixedUpdate()
|
|
{
|
|
entityComponents.ForEach(x => x.OnFixedUpdate(Time.fixedDeltaTime));
|
|
}
|
|
private void LateUpdate()
|
|
{
|
|
entityComponents.ForEach(x => x.OnLateUpdate(Time.deltaTime));
|
|
}
|
|
public void AddListener<T>(Action<T> action) => genericEvent.AddListener<T>(action);
|
|
public void Invoke<T>(T value) => genericEvent.Invoke<T>(value);
|
|
public void RemoveListener<T>(Action<T> action) => genericEvent.RemoveListener<T>(action);
|
|
public void AddListener<T>(string key, Action<T> action) => genericEvent.AddListener<T>(key, action);
|
|
public void Invoke<T>(string key, T value) => genericEvent.Invoke<T>(key, value);
|
|
public void Invoke<T>() where T : new() => genericEvent.Invoke<T>();
|
|
public void RemoveListener<T>(string key, Action<T> action) => genericEvent.RemoveListener<T>(key, action);
|
|
public T Get<T>(string key = Constant.System.Internal)
|
|
{
|
|
var value = genericEvent.Get<T>(key);
|
|
if (value is not null || !typeof(T).IsAssignableFrom(typeof(Component))) return value;
|
|
if (!TryGetComponent<T>(out var component)) return default(T);
|
|
Set<T>(component);
|
|
return component;
|
|
}
|
|
public void Set<T>(T value) => genericEvent.Set<T>(value);
|
|
public void Set<T>(string key = Constant.System.Internal, T value = default) => genericEvent.Set<T>(key, value);
|
|
public T GetContext<T>(T value = default) => processor.GetContext<T>(value);
|
|
public void AddProcessor<T>(Func<T, T> func) => processor.AddProcessor<T>(func);
|
|
public void RemoveProcessor<T>(Func<T, T> func) => processor.RemoveProcessor<T>(func);
|
|
public T GetContext<T>(string key, T value) => processor.GetContext<T>(value);
|
|
public void AddProcessor<T>(string key, Func<T, T> func) => processor.AddProcessor<T>(key, func);
|
|
public void RemoveProcessor<T>(string key, Func<T, T> func) => processor.RemoveProcessor<T>(key, func);
|
|
|
|
public void RegisterCallback<T>(T t)
|
|
{
|
|
var value = GetCallbacks<T>() as List<T>;
|
|
value!.Add(t);
|
|
}
|
|
|
|
public void UnRegisterCallback<T>(T t)
|
|
{
|
|
var value = GetCallbacks<T>() as List<T>;
|
|
value!.Remove(t);
|
|
}
|
|
|
|
public IEnumerable<T> GetCallbacks<T>()
|
|
{
|
|
var value = Get<List<T>>(nameof(ICallback)).CreateOrAddIfEmety(() =>
|
|
{
|
|
List<T> newList = new();
|
|
Set<List<T>>(nameof(ICallback), newList);
|
|
|
|
return newList;
|
|
});
|
|
if (value is null)
|
|
{
|
|
Debug.LogWarning("List is Null");
|
|
}
|
|
return value;
|
|
}
|
|
|
|
|
|
}
|
|
#if UNITY_EDITOR
|
|
[UnityEditor.CustomEditor(typeof(Entity))]
|
|
public class EntityInspector : BITInspector<Entity>
|
|
{
|
|
public override VisualElement CreateInspectorGUI()
|
|
{
|
|
FillDefaultInspector();
|
|
CreateSubTitle("Identity");
|
|
var idLabel = root.Create<Label>();
|
|
idLabel.text = agent.Id.ToString();
|
|
return root;
|
|
}
|
|
}
|
|
#endif
|
|
} |