BITKit/Src/Unity/Scripts/Entity/Core/Entity.cs

136 lines
5.2 KiB
C#
Raw Normal View History

2023-06-05 19:57:17 +08:00
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
2023-09-01 14:35:05 +08:00
using System.Reflection;
using System.Threading;
2023-06-29 14:57:11 +08:00
using BITKit.Core.Entites;
2023-09-01 14:35:05 +08:00
using Cysharp.Threading.Tasks;
2023-06-05 19:57:17 +08:00
using UnityEngine.UIElements;
2023-08-23 01:59:26 +08:00
// ReSharper disable RedundantTypeArgumentsOfMethod
2023-06-05 19:57:17 +08:00
namespace BITKit.Entities
{
public class Entity : MonoBehaviour, IEntity
{
2023-06-29 14:57:11 +08:00
private readonly GenericEvent genericEvent = new();
private readonly Processor processor = new();
2023-06-05 19:57:17 +08:00
public IEntityComponent[] entityComponents { get; set; }
2023-08-23 01:59:26 +08:00
public ulong Id { get; private set; }
2023-09-01 14:35:05 +08:00
private CancellationToken _cancellationToken;
2023-08-23 01:59:26 +08:00
private bool isInitialized;
private void Awake()
2023-06-05 19:57:17 +08:00
{
2023-08-23 01:59:26 +08:00
Id = (ulong)Guid.NewGuid().GetHashCode();
2023-09-01 14:35:05 +08:00
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
Set(_cancellationToken);
2023-08-23 01:59:26 +08:00
foreach (var serviceRegister in GetComponentsInChildren<IServiceRegister>(true))
{
genericEvent.Set(serviceRegister.BaseType, serviceRegister);
}
2023-06-29 14:57:11 +08:00
entityComponents = GetComponentsInChildren<IEntityComponent>(true).Distinct().ToArray();
2023-09-01 14:35:05 +08:00
foreach (var x in entityComponents)
{
foreach (var att in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
{
genericEvent.Set(att.Type, x);
}
}
2023-06-05 19:57:17 +08:00
entityComponents.ForEach(x => x.Initialize(this));
2023-08-23 01:59:26 +08:00
UnityEntitiesService.Register(this);
2023-06-05 19:57:17 +08:00
}
2023-08-23 01:59:26 +08:00
private void Start()
2023-06-05 19:57:17 +08:00
{
entityComponents.ForEach(x => x.OnAwake());
entityComponents.ForEach(x => x.OnStart());
2023-08-23 01:59:26 +08:00
isInitialized = true;
2023-06-05 19:57:17 +08:00
}
2023-08-23 01:59:26 +08:00
private void OnDestroy()
2023-06-05 19:57:17 +08:00
{
2023-08-23 01:59:26 +08:00
if (isInitialized)
{
entityComponents.ForEach(x => x.OnDestroyComponent());
}
UnityEntitiesService.UnRegister(this);
2023-06-05 19:57:17 +08:00
}
2023-08-23 01:59:26 +08:00
private void Update()
2023-06-05 19:57:17 +08:00
{
entityComponents.ForEach(x => x.OnUpdate(Time.deltaTime));
}
2023-08-23 01:59:26 +08:00
private void FixedUpdate()
2023-06-05 19:57:17 +08:00
{
entityComponents.ForEach(x => x.OnFixedUpdate(Time.fixedDeltaTime));
}
2023-08-23 01:59:26 +08:00
private void LateUpdate()
2023-06-05 19:57:17 +08:00
{
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);
2023-08-23 01:59:26 +08:00
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;
2023-06-05 19:57:17 +08:00
}
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>;
2023-08-23 01:59:26 +08:00
value!.Add(t);
2023-06-05 19:57:17 +08:00
}
public void UnRegisterCallback<T>(T t)
{
var value = GetCallbacks<T>() as List<T>;
2023-08-23 01:59:26 +08:00
value!.Remove(t);
2023-06-05 19:57:17 +08:00
}
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;
}
2023-08-23 01:59:26 +08:00
2023-06-05 19:57:17 +08:00
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(Entity))]
public class EntityInspector : BITInspector<Entity>
{
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
2023-08-23 01:59:26 +08:00
CreateSubTitle("Identity");
2023-06-05 19:57:17 +08:00
var idLabel = root.Create<Label>();
idLabel.text = agent.Id.ToString();
return root;
}
}
#endif
}