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

188 lines
5.5 KiB
C#
Raw Normal View History

2023-06-29 14:57:11 +08:00
using System;
2023-08-23 01:59:26 +08:00
using System.Collections.Concurrent;
2023-06-29 14:57:11 +08:00
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using BITKit;
using BITKit.Core.Entites;
2023-08-11 23:57:37 +08:00
using BITKit.Entities;
2023-06-29 14:57:11 +08:00
using UnityEngine;
using Cysharp.Threading.Tasks;
2023-08-11 23:57:37 +08:00
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
{
2023-08-23 01:59:26 +08:00
add => UnityEntitiesService.OnAdd += value;
remove => UnityEntitiesService.OnAdd -= value;
2023-08-11 23:57:37 +08:00
}
public event Action<IEntity> OnRemove
{
2023-08-23 01:59:26 +08:00
add => UnityEntitiesService.OnRemove += value;
remove => UnityEntitiesService.OnRemove -= value;
2023-08-11 23:57:37 +08:00
}
2023-08-23 01:59:26 +08:00
public IEntity[] Entities => UnityEntitiesService.Entities;
2023-08-11 23:57:37 +08:00
public bool Register(IEntity entity)
{
2023-08-23 01:59:26 +08:00
return UnityEntitiesService.Register(entity);
2023-08-11 23:57:37 +08:00
}
public bool UnRegister(IEntity entity)
{
2023-08-23 01:59:26 +08:00
return UnityEntitiesService.UnRegister(entity);
2023-08-11 23:57:37 +08:00
}
2023-08-23 01:59:26 +08:00
public CancellationToken CancellationToken => UnityEntitiesService.CancellationToken;
2023-08-11 23:57:37 +08:00
2023-08-23 01:59:26 +08:00
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
2023-08-11 23:57:37 +08:00
2023-10-06 23:43:19 +08:00
public IEntity[] Query<T>()
2023-08-11 23:57:37 +08:00
{
2023-08-23 01:59:26 +08:00
return UnityEntitiesService.Query<T>();
2023-08-11 23:57:37 +08:00
}
2023-10-06 23:43:19 +08:00
public T[] QueryComponents<T>()
2023-08-11 23:57:37 +08:00
{
2023-08-23 01:59:26 +08:00
return UnityEntitiesService.QueryComponents<T>();
2023-08-11 23:57:37 +08:00
}
2023-10-06 23:43:19 +08:00
public (T, T1)[] QueryComponents<T, T1>()
2023-08-11 23:57:37 +08:00
{
2023-08-23 01:59:26 +08:00
return UnityEntitiesService.QueryComponents<T, T1>();
2023-08-11 23:57:37 +08:00
}
2023-10-06 23:43:19 +08:00
public (T, T1, T2)[] QueryComponents<T, T1, T2>()
2023-08-11 23:57:37 +08:00
{
2023-08-23 01:59:26 +08:00
return UnityEntitiesService.QueryComponents<T, T1, T2>();
2023-08-11 23:57:37 +08:00
}
}
2023-06-29 14:57:11 +08:00
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
{
2023-10-06 23:43:19 +08:00
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
2023-08-23 01:59:26 +08:00
private static void Initialize()
2023-06-29 14:57:11 +08:00
{
2023-08-23 01:59:26 +08:00
Dictionary.Clear();
RegisterQueue.Clear();
UnRegisterQueue.Clear();
2023-06-29 14:57:11 +08:00
}
2023-08-23 01:59:26 +08:00
public static bool Register(IEntity entity)
2023-06-29 14:57:11 +08:00
{
RegisterQueue.Enqueue(entity);
return true;
}
2023-08-23 01:59:26 +08:00
public static bool UnRegister(IEntity entity)
2023-06-29 14:57:11 +08:00
{
UnRegisterQueue.Enqueue(entity);
return false;
}
2023-08-23 01:59:26 +08:00
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);
2023-06-29 14:57:11 +08:00
private void LateUpdate()
{
while (RegisterQueue.TryDequeue(out var entity))
{
2023-08-23 01:59:26 +08:00
Dictionary.AddOrUpdate(entity.Id,entity,(x,y)=>entity);
2023-08-11 23:57:37 +08:00
OnAdd?.Invoke(entity);
2023-06-29 14:57:11 +08:00
}
while (UnRegisterQueue.TryDequeue(out var entity))
{
2023-09-01 14:35:05 +08:00
if (Dictionary.TryRemove(entity.Id))
2023-08-11 23:57:37 +08:00
{
OnRemove?.Invoke(entity);
}
2023-06-29 14:57:11 +08:00
}
}
2023-08-23 01:59:26 +08:00
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>();
2023-10-06 23:43:19 +08:00
public static IEntity[] Query<T>()
2023-06-29 14:57:11 +08:00
{
2023-08-11 23:57:37 +08:00
return Entities.Where(x => ((Entity)x).TryGetComponentAny<T>(out _)).ToArray();
}
2023-08-23 01:59:26 +08:00
T[] IEntitiesService.QueryComponents<T>()=>QueryComponents<T>();
2023-10-06 23:43:19 +08:00
public static T[] QueryComponents<T>()
2023-08-11 23:57:37 +08:00
{
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;
}
2023-08-23 01:59:26 +08:00
(T, T1)[] IEntitiesService.QueryComponents<T,T1>()=>QueryComponents<T,T1>();
2023-10-06 23:43:19 +08:00
public static (T, T1)[] QueryComponents<T, T1>()
2023-08-11 23:57:37 +08:00
{
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;
}
2023-08-23 01:59:26 +08:00
(T, T1, T2)[] IEntitiesService.QueryComponents<T,T1,T2>()=>QueryComponents<T,T1,T2>();
2023-10-06 23:43:19 +08:00
public static (T, T1, T2)[] QueryComponents<T, T1, T2>()
2023-08-11 23:57:37 +08:00
{
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;
2023-06-29 14:57:11 +08:00
}
}