188 lines
5.5 KiB
C#
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;
|
|
}
|
|
}
|