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

188 lines
5.5 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using BITKit;
using BITKit.Core.Entites;
using BITKit.Entities;
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine.Pool;
using IEntity = BITKit.Core.Entites.IEntity;
using IEntityComponent = BITKit.Core.Entites.IEntityComponent;
[Serializable]
public class UnityEntitiesServiceSingleton:IEntitiesService
{
public event Action<IEntity> OnAdd
{
add => UnityEntitiesService.OnAdd += value;
remove => UnityEntitiesService.OnAdd -= value;
}
public event Action<IEntity> OnRemove
{
add => UnityEntitiesService.OnRemove += value;
remove => UnityEntitiesService.OnRemove -= value;
}
public IEntity[] Entities => UnityEntitiesService.Entities;
public bool Register(IEntity entity)
{
return UnityEntitiesService.Register(entity);
}
public bool UnRegister(IEntity entity)
{
return UnityEntitiesService.UnRegister(entity);
}
public CancellationToken CancellationToken => UnityEntitiesService.CancellationToken;
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
public IEntity[] Query<T>()
{
return UnityEntitiesService.Query<T>();
}
public T[] QueryComponents<T>()
{
return UnityEntitiesService.QueryComponents<T>();
}
public (T, T1)[] QueryComponents<T, T1>()
{
return UnityEntitiesService.QueryComponents<T, T1>();
}
public (T, T1, T2)[] QueryComponents<T, T1, T2>()
{
return UnityEntitiesService.QueryComponents<T, T1, T2>();
}
}
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Initialize()
{
Dictionary.Clear();
RegisterQueue.Clear();
UnRegisterQueue.Clear();
}
public static bool Register(IEntity entity)
{
RegisterQueue.Enqueue(entity);
return true;
}
public static bool UnRegister(IEntity entity)
{
UnRegisterQueue.Enqueue(entity);
return false;
}
public static CancellationToken CancellationToken;
private static readonly ConcurrentDictionary<ulong,IEntity> Dictionary=new();
private static readonly Queue<IEntity> RegisterQueue = new();
private static readonly Queue<IEntity> UnRegisterQueue = new();
private void Awake()
{
CancellationToken = gameObject.GetCancellationTokenOnDestroy();
}
event Action<IEntity> IEntitiesService.OnAdd
{
add => OnAdd += value;
remove => OnAdd -= value;
}
event Action<IEntity> IEntitiesService.OnRemove
{
add => OnRemove += value;
remove => OnRemove -= value;
}
public static event Action<IEntity> OnAdd;
public static event Action<IEntity> OnRemove;
IEntity[] IEntitiesService.Entities => Entities;
public static IEntity[] Entities => Dictionary.Values.ToArray();
bool IEntitiesService.Register(IEntity entity) => Register(entity);
bool IEntitiesService.UnRegister(IEntity entity) => UnRegister(entity);
private void LateUpdate()
{
while (RegisterQueue.TryDequeue(out var entity))
{
Dictionary.AddOrUpdate(entity.Id,entity,(x,y)=>entity);
OnAdd?.Invoke(entity);
}
while (UnRegisterQueue.TryDequeue(out var entity))
{
if (Dictionary.TryRemove(entity.Id))
{
OnRemove?.Invoke(entity);
}
}
}
CancellationToken IEntitiesService.CancellationToken => CancellationToken;
public static IEntity Get(ulong id)=>Dictionary[id];
IEntity IEntitiesService.Get(ulong id)=>Get(id);
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
public static IEntity[] Query<T>()
{
return Entities.Where(x => ((Entity)x).TryGetComponentAny<T>(out _)).ToArray();
}
T[] IEntitiesService.QueryComponents<T>()=>QueryComponents<T>();
public static T[] QueryComponents<T>()
{
var list = ListPool<T>.Get();
foreach (var iEntity in Entities)
{
switch (iEntity as Entity)
{
case { } x when x.TryGetComponentAny<T>(out var t):
list.Add((t));
break;
}
}
var value = list.ToArray();
list.Clear();
ListPool<T>.Release(list);
return value;
}
(T, T1)[] IEntitiesService.QueryComponents<T,T1>()=>QueryComponents<T,T1>();
public static (T, T1)[] QueryComponents<T, T1>()
{
var list = ListPool<(T t, T1 t1)>.Get();
foreach (var iEntity in Entities)
{
switch (iEntity as Entity)
{
case var x when x != null && x.TryGetComponentAny<T>(out var t) && x.TryGetComponentAny<T1>(out var t1):
list.Add((t, t1));
break;
}
}
var value = list.ToArray();
list.Clear();
ListPool<(T t, T1 t1)>.Release(list);
return value;
}
(T, T1, T2)[] IEntitiesService.QueryComponents<T,T1,T2>()=>QueryComponents<T,T1,T2>();
public static (T, T1, T2)[] QueryComponents<T, T1, T2>()
{
var list = ListPool<(T t, T1 t1, T2 t2)>.Get();
foreach (var iEntity in Entities)
{
switch (iEntity as Entity)
{
case var x when x != null && x.TryGetComponentAny<T>(out var t) && x.TryGetComponentAny<T1>(out var t1) && x.TryGetComponentAny<T2>(out var t2):
list.Add((t, t1, t2));
break;
}
}
var value = list.ToArray();
list.Clear();
ListPool<(T t, T1 t1, T2 t2)>.Release(list);
return value;
}
}