using System; using System.Collections.Generic; using UnityEngine; using System.Linq; using System.Reflection; 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; } private CancellationToken _cancellationToken; private bool isInitialized; private void Awake() { Id = (ulong)Guid.NewGuid().GetHashCode(); _cancellationToken = gameObject.GetCancellationTokenOnDestroy(); Set(_cancellationToken); foreach (var serviceRegister in GetComponentsInChildren(true)) { genericEvent.Set(serviceRegister.BaseType, serviceRegister); } entityComponents = GetComponentsInChildren(true).Distinct().ToArray(); foreach (var x in entityComponents) { foreach (var att in x.GetType().GetCustomAttributes()) { genericEvent.Set(att.Type, x); } } entityComponents.ForEach(x => x.Initialize(this)); UnityEntitiesService.Register(this); } private void Start() { 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(Action action) => genericEvent.AddListener(action); public void Invoke(T value) => genericEvent.Invoke(value); public void RemoveListener(Action action) => genericEvent.RemoveListener(action); public void AddListener(string key, Action action) => genericEvent.AddListener(key, action); public void Invoke(string key, T value) => genericEvent.Invoke(key, value); public void Invoke() where T : new() => genericEvent.Invoke(); public void RemoveListener(string key, Action action) => genericEvent.RemoveListener(key, action); public T Get(string key = Constant.System.Internal) { var value = genericEvent.Get(key); if (value is not null || !typeof(T).IsAssignableFrom(typeof(Component))) return value; if (!TryGetComponent(out var component)) return default(T); Set(component); return component; } public void Set(T value) => genericEvent.Set(value); public void Set(string key = Constant.System.Internal, T value = default) => genericEvent.Set(key, value); public T GetContext(T value = default) => processor.GetContext(value); public void AddProcessor(Func func) => processor.AddProcessor(func); public void RemoveProcessor(Func func) => processor.RemoveProcessor(func); public T GetContext(string key, T value) => processor.GetContext(value); public void AddProcessor(string key, Func func) => processor.AddProcessor(key, func); public void RemoveProcessor(string key, Func func) => processor.RemoveProcessor(key, func); public void RegisterCallback(T t) { var value = GetCallbacks() as List; value!.Add(t); } public void UnRegisterCallback(T t) { var value = GetCallbacks() as List; value!.Remove(t); } public IEnumerable GetCallbacks() { var value = Get>(nameof(ICallback)).CreateOrAddIfEmety(() => { List newList = new(); Set>(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 { public override VisualElement CreateInspectorGUI() { FillDefaultInspector(); CreateSubTitle("Identity"); var idLabel = root.Create