This commit is contained in:
CortexCore
2025-03-24 14:42:40 +08:00
parent 18239a5ae4
commit 9845d20f7f
99 changed files with 5418 additions and 5512 deletions

View File

@@ -1,284 +1,623 @@
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Threading;
using kcp2k;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Unity.Mathematics;
namespace BITKit.Entities
{
public class EntitiesService:IEntitiesService,IDisposable
public static class EntitiesServiceExtensions
{
private readonly ILogger<EntitiesService> _logger;
private readonly IFixedTicker _ticker;
private static int _count;
private static readonly ConcurrentQueue<IEntity> OnAddQueue = new();
private static ConcurrentDictionary<int, HashSet<int>> TypeCaches = new();
public EntitiesService(ILogger<EntitiesService> logger, IFixedTicker ticker)
internal static T GetRequiredServiceWithId<T>(this IServiceProvider serviceProvider, int id)
{
if (_count > 0)
{
throw new MulticastNotSupportedException();
}
_count++;
return serviceProvider.GetRequiredService<T>();
}
}
public unsafe class EntitiesService : IEntitiesService, IDisposable
{
private static int _count;
private readonly ILogger<EntitiesService> _logger;
private readonly ITicker _ticker;
private readonly ConcurrentQueue<IEntity> _onAddQueue = new();
private readonly Dictionary<int, HashSet<int>> _typeCaches = new();
private readonly Dictionary<int, ConcurrentDictionary<int, object>> _typeInstances = new();
private readonly ConcurrentDictionary<int, object> _staticCaches = new();
public EntitiesService(ILogger<EntitiesService> logger, ITicker ticker)
{
_logger = logger;
_ticker = ticker;
_ticker.Add(OnTick);
_pool = new(ObjectGenerator, null, 64);
_count++;
logger.LogInformation($"已创建EntitiesService,当前有:{_count}个实例");
_ticker?.Add(OnTick);
}
private void OnTick(float obj)
{
while (OnAddQueue.TryDequeue(out var entity))
while (_onAddQueue.TryDequeue(out var entity))
{
OnAdd?.Invoke(entity);
foreach (var serviceDescriptor in entity.ServiceCollection)
{
var typeHash = serviceDescriptor.ServiceType.GetHashCode();
var hashSet = TypeCaches.GetOrCreate(typeHash);
hashSet.Add(entity.Id);
}
_staticCaches.Clear();
MakeCache(entity);
}
}
private static readonly ConcurrentDictionary<int, IEntity> Entities = new();
private void MakeCache(IEntity entity)
{
foreach (var serviceDescriptor in entity.ServiceCollection)
{
var typeHash = serviceDescriptor.ServiceType.GetHashCode();
var hashSet = _typeCaches.GetOrCreate(typeHash);
hashSet.Add(entity.Id);
}
}
private readonly Dictionary<int, IEntity> _entitiesInternal = new();
public event Action<IEntity> OnAdd;
public event Action<IEntity> OnRemove;
IReadOnlyDictionary<int, IEntity> IEntitiesService.Entities => Entities;
IReadOnlyDictionary<int, IEntity> IEntitiesService.Entities => _entitiesInternal;
private readonly Pool<HashSet<int>> _pool;
private HashSet<int> ObjectGenerator()
{
return new HashSet<int>(math.max(8192, _typeCaches.Count * 2));
}
public bool Register(IEntity entity)
{
if (!Entities.TryAdd(entity.Id, entity)) return false;
OnAddQueue.Enqueue(entity);
if (!_entitiesInternal.TryAdd(entity.Id, entity)) return false;
if (_ticker is not null)
{
_onAddQueue.Enqueue(entity);
}
else
{
_staticCaches.Clear();
OnAdd?.Invoke(entity);
MakeCache(entity);
}
return true;
}
public bool UnRegister(IEntity entity)
{
if (!Entities.TryRemove(entity.Id, out _)) return false;
if (!_entitiesInternal.TryRemove(entity.Id)) return false;
OnRemove?.Invoke(entity);
foreach (var serviceDescriptor in entity.ServiceCollection)
{
var typeHash = serviceDescriptor.ServiceType.GetHashCode();
var hashSet = TypeCaches.GetOrCreate(typeHash);
var hashSet = _typeCaches.GetOrCreate(typeHash);
hashSet.Remove(entity.Id);
}
_typeInstances.TryRemove(entity.Id);
_staticCaches.Clear();
return true;
}
public CancellationToken CancellationToken => _cancellationTokenSource.Token;
private readonly CancellationTokenSource _cancellationTokenSource = new();
public IEntity Get(int id)
{
return Entities[id];
return _entitiesInternal[id];
}
public bool TryGetEntity(int id, out IEntity entity)
{
return Entities.TryGetValue(id, out entity);
return _entitiesInternal.TryGetValue(id, out entity);
}
public IEntity GetOrAdd(int id, Func<int, IEntity> factory)
{
return Entities.GetOrAdd(id, factory);
}
public IEntity[] Query<T>()
{
throw new NotImplementedException("Obsoleted");
}
public T[] QueryComponents<T>()
{
var list = new List<T>();
foreach (var entity in Entities.Values)
if (_entitiesInternal.TryGetValue(id, out var current))
{
if (entity.ServiceProvider.GetService<T>() is { } t1)
{
list.Add(t1);
}
_entitiesInternal.TryAdd(id, current = factory.Invoke(id));
}
return list.ToArray();
// return _queryCache.GetOrAdd(typeof(T), type =>
// {
// return _entities.Values.Where(entity => entity.TryGetComponent(out T component)).ToArray();
// }).Cast<T>().ToArray();
return current;
}
public (T, T1)[] QueryComponents<T, T1>()
public Span<T> QueryComponents<T>() where T : class
{
var list = new List<(T, T1)>();
foreach (var entity in Entities.Values)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2)
{
list.Add((t1, t2));
}
}
return list.ToArray();
// List<(T, T1)> list = new();
// foreach (var entity in _entities.Values)
// {
// if (entity.TryGetComponent(out T t) && entity.TryGetComponent(out T1 t1))
// list.Add((t, t1));
// }
// return list.ToArray();
}
public (T, T1, T2)[] QueryComponents<T, T1, T2>()
{
var list = new List<(T, T1, T2)>();
foreach (var entity in Entities.Values)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2 &&
entity.ServiceProvider.GetService<T2>() is { } t3)
{
list.Add((t1, t2, t3));
}
}
return list.ToArray();
// List<(T, T1, T2)> list = new();
// foreach (var entity in _entities.Values)
// {
// if (entity.TryGetComponent(out T t) && entity.TryGetComponent(out T1 t1) && entity.TryGetComponent(out T2 t2))
// list.Add((t, t1, t2));
// }
// return list.ToArray();
}
var pool = ArrayPool<T>.Shared;
public (T, T1, T2, T3)[] QueryComponents<T, T1, T2, T3>()
{
var list = new List<(T, T1, T2, T3)>();
foreach (var entity in Entities.Values)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2 &&
entity.ServiceProvider.GetService<T2>() is { } t3 &&
entity.ServiceProvider.GetService<T3>() is { } t4)
{
list.Add((t1, t2, t3, t4));
}
}
return list.ToArray();
// List<(T, T1, T2, T3)> list = new();
// foreach (var entity in _entities.Values)
// {
// if (entity.TryGetComponent(out T t) && entity.TryGetComponent(out T1 t1) && entity.TryGetComponent(out T2 t2) && entity.TryGetComponent(out T3 t3))
// list.Add((t, t1, t2, t3));
// }
// return list.ToArray();
}
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
public (T, T1, T2, T3, T4)[] QueryComponents<T, T1, T2, T3, T4>()
{
var list = new List<(T, T1, T2, T3, T4)>();
foreach (var entity in Entities.Values)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2 &&
entity.ServiceProvider.GetService<T2>() is { } t3 &&
entity.ServiceProvider.GetService<T3>() is { } t4 &&
entity.ServiceProvider.GetService<T4>() is { } t5)
{
list.Add((t1, t2, t3, t4, t5));
}
}
return list.ToArray();
// List<(T, T1, T2, T3, T4)> list = new();
// foreach (var entity in _entities.Values)
// {
// if (entity.TryGetComponent(out T t) && entity.TryGetComponent(out T1 t1) && entity.TryGetComponent(out T2 t2) && entity.TryGetComponent(out T3 t3) && entity.TryGetComponent(out T4 t4))
// list.Add((t, t1, t2, t3, t4));
// }
// return list.ToArray();
}
var array = pool.Rent(hashset.Count);
var collection = _pool.Take();
collection.Clear();
public (T, T1, T2, T3, T4, T5)[] QueryComponents<T, T1, T2, T3, T4, T5>()
{
var list = new List<(T, T1, T2, T3, T4, T5)>();
foreach (var entity in Entities.Values)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2 &&
entity.ServiceProvider.GetService<T2>() is { } t3 &&
entity.ServiceProvider.GetService<T3>() is { } t4 &&
entity.ServiceProvider.GetService<T4>() is { } t5 &&
entity.ServiceProvider.GetService<T5>() is { } t6)
{
list.Add((t1, t2, t3, t4, t5, t6));
}
}
return list.ToArray();
// List<(T, T1, T2, T3, T4, T5)> list = new();
// foreach (var entity in _entities.Values)
// {
// if (entity.TryGetComponent(out T t) && entity.TryGetComponent(out T1 t1) && entity.TryGetComponent(out T2 t2) && entity.TryGetComponent(out T3 t3) && entity.TryGetComponent(out T4 t4) && entity.TryGetComponent(out T5 t5))
// list.Add((t, t1, t2, t3, t4, t5));
// }
// return list.ToArray();
}
collection.UnionWith(hashset);
public (T, T1, T2, T3, T4, T5, T6)[] QueryComponents<T, T1, T2, T3, T4, T5, T6>()
{
var list = new List<(T, T1, T2, T3, T4, T5, T6)>();
foreach (var entity in Entities.Values)
var i = 0;
foreach (var id in collection)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2 &&
entity.ServiceProvider.GetService<T2>() is { } t3 &&
entity.ServiceProvider.GetService<T3>() is { } t4 &&
entity.ServiceProvider.GetService<T4>() is { } t5 &&
entity.ServiceProvider.GetService<T5>() is { } t6 &&
entity.ServiceProvider.GetService<T6>() is { } t7)
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
list.Add((t1, t2, t3, t4, t5, t6, t7));
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
array[i] = Unsafe.As<T>(v0);
i++;
}
return list.ToArray();
// List<(T, T1, T2, T3, T4, T5, T6)> list = new();
// foreach (var entity in _entities.Values)
// {
// if (entity.TryGetComponent(out T t) && entity.TryGetComponent(out T1 t1) && entity.TryGetComponent(out T2 t2) && entity.TryGetComponent(out T3 t3) && entity.TryGetComponent(out T4 t4) && entity.TryGetComponent(out T5 t5) && entity.TryGetComponent(out T6 t6))
// list.Add((t, t1, t2, t3, t4, t5, t6));
// }
// return list.ToArray();
try
{
return new Span<T>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
}
public ValueTuple<T, T1, T2, T3, T4, T5, T6, TRest>[] QueryComponents<T, T1, T2, T3, T4, T5, T6, TRest>()
where TRest : struct
public Span<(T, T1)> QueryComponents<T, T1>() where T : class where T1 : class
{
var list = new List<ValueTuple<T, T1, T2, T3, T4, T5, T6, TRest>>();
foreach (var entity in Entities.Values)
var pool = ArrayPool<(T, T1)>.Shared;
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode());
var count = math.max(hashset.Count, t1Set.Count);
var array = pool.Rent(count);
var collection = _pool.Take();
collection.Clear();
collection.UnionWith(hashset);
collection.IntersectWith(t1Set);
var i = 0;
foreach (var id in collection)
{
if (entity.ServiceProvider.GetService<T>() is { } t1 &&
entity.ServiceProvider.GetService<T1>() is { } t2 &&
entity.ServiceProvider.GetService<T2>() is { } t3 &&
entity.ServiceProvider.GetService<T3>() is { } t4 &&
entity.ServiceProvider.GetService<T4>() is { } t5 &&
entity.ServiceProvider.GetService<T5>() is { } t6 &&
entity.ServiceProvider.GetService<T6>() is { } t7 &&
entity.ServiceProvider.GetService<TRest>() is { } t8)
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
var h1 = typeof(T1).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
list.Add(new ValueTuple<T, T1, T2, T3, T4, T5, T6, TRest>(t1, t2, t3, t4, t5, t6, t7, t8));
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
if (instances.TryGetValue(h1, out var v1) is false)
{
instances[h1] = v1 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T1>();
}
array[i] = (Unsafe.As<T>(v0), Unsafe.As<T1>(v1));
i++;
}
try
{
return new Span<(T, T1)>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
}
public Span<(T, T1, T2)> QueryComponents<T, T1, T2>() where T : class where T1 : class where T2 : class
{
var pool = ArrayPool<(T, T1, T2)>.Shared;
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode());
var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode());
var count = math.max(hashset.Count, math.max(t1Set.Count, t2Set.Count));
var array = pool.Rent(count);
var collection = _pool.Take();
collection.Clear();
collection.UnionWith(hashset);
collection.IntersectWith(t1Set);
collection.IntersectWith(t2Set);
var i = 0;
foreach (var id in collection)
{
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
var h1 = typeof(T1).GetHashCode();
var h2 = typeof(T2).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
if (instances.TryGetValue(h1, out var v1) is false)
{
instances[h1] = v1 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T1>();
}
if (instances.TryGetValue(h2, out var v2) is false)
{
instances[h2] = v2 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T2>();
}
array[i] = (Unsafe.As<T>(v0), Unsafe.As<T1>(v1), Unsafe.As<T2>(v2));
i++;
}
try
{
return new Span<(T, T1, T2)>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
}
public Span<(T, T1, T2, T3)> QueryComponents<T, T1, T2, T3>()
where T : class where T1 : class where T2 : class where T3 : class
{
var pool = ArrayPool<(T, T1, T2, T3)>.Shared;
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode());
var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode());
var t3Set = _typeCaches.GetOrCreate(typeof(T3).GetHashCode());
var count = math.max(hashset.Count, math.max(t1Set.Count, math.max(t2Set.Count, t3Set.Count)));
var array = pool.Rent(count);
var collection = _pool.Take();
collection.Clear();
collection.UnionWith(hashset);
collection.IntersectWith(t1Set);
collection.IntersectWith(t2Set);
collection.IntersectWith(t3Set);
var i = 0;
foreach (var id in collection)
{
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
var h1 = typeof(T1).GetHashCode();
var h2 = typeof(T2).GetHashCode();
var h3 = typeof(T3).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
if (instances.TryGetValue(h1, out var v1) is false)
{
instances[h1] = v1 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T1>();
}
if (instances.TryGetValue(h2, out var v2) is false)
{
instances[h2] = v2 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T2>();
}
if (instances.TryGetValue(h3, out var v3) is false)
{
instances[h3] = v3 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T3>();
}
array[i] = (Unsafe.As<T>(v0), Unsafe.As<T1>(v1), Unsafe.As<T2>(v2), Unsafe.As<T3>(v3));
i++;
}
try
{
return new Span<(T, T1, T2, T3)>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
}
public Span<(T, T1, T2, T3, T4)> QueryComponents<T, T1, T2, T3, T4>() where T : class
where T1 : class
where T2 : class
where T3 : class
where T4 : class
{
var pool = ArrayPool<(T, T1, T2, T3, T4)>.Shared;
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode());
var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode());
var t3Set = _typeCaches.GetOrCreate(typeof(T3).GetHashCode());
var t4Set = _typeCaches.GetOrCreate(typeof(T4).GetHashCode());
var count = math.max(hashset.Count,
math.max(t1Set.Count, math.max(t2Set.Count, math.max(t3Set.Count, t4Set.Count))));
var array = pool.Rent(count);
var collection = _pool.Take();
collection.Clear();
collection.UnionWith(hashset);
collection.IntersectWith(t1Set);
collection.IntersectWith(t2Set);
collection.IntersectWith(t3Set);
collection.IntersectWith(t4Set);
var i = 0;
foreach (var id in collection)
{
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
var h1 = typeof(T1).GetHashCode();
var h2 = typeof(T2).GetHashCode();
var h3 = typeof(T3).GetHashCode();
var h4 = typeof(T4).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
if (instances.TryGetValue(h1, out var v1) is false)
{
instances[h1] = v1 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T1>();
}
if (instances.TryGetValue(h2, out var v2) is false)
{
instances[h2] = v2 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T2>();
}
if (instances.TryGetValue(h3, out var v3) is false)
{
instances[h3] = v3 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T3>();
}
if (instances.TryGetValue(h4, out var v4) is false)
{
instances[h4] = v4 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T4>();
}
array[i] = (Unsafe.As<T>(v0), Unsafe.As<T1>(v1), Unsafe.As<T2>(v2), Unsafe.As<T3>(v3),
Unsafe.As<T4>(v4));
i++;
}
try
{
return new Span<(T, T1, T2, T3, T4)>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
}
public Span<(T, T1, T2, T3, T4, T5)> QueryComponents<T, T1, T2, T3, T4, T5>() where T : class
where T1 : class
where T2 : class
where T3 : class
where T4 : class
where T5 : class
{
var pool = ArrayPool<(T, T1, T2, T3, T4, T5)>.Shared;
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode());
var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode());
var t3Set = _typeCaches.GetOrCreate(typeof(T3).GetHashCode());
var t4Set = _typeCaches.GetOrCreate(typeof(T4).GetHashCode());
var t5Set = _typeCaches.GetOrCreate(typeof(T5).GetHashCode());
var count = math.max(hashset.Count,
math.max(t1Set.Count,
math.max(t2Set.Count, math.max(t3Set.Count, math.max(t4Set.Count, t5Set.Count)))));
var array = pool.Rent(count);
var collection = _pool.Take();
collection.Clear();
collection.UnionWith(hashset);
collection.IntersectWith(t1Set);
collection.IntersectWith(t2Set);
collection.IntersectWith(t3Set);
collection.IntersectWith(t4Set);
collection.IntersectWith(t5Set);
var i = 0;
foreach (var id in collection)
{
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
var h1 = typeof(T1).GetHashCode();
var h2 = typeof(T2).GetHashCode();
var h3 = typeof(T3).GetHashCode();
var h4 = typeof(T4).GetHashCode();
var h5 = typeof(T5).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
if (instances.TryGetValue(h1, out var v1) is false)
{
instances[h1] = v1 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T1>();
}
if (instances.TryGetValue(h2, out var v2) is false)
{
instances[h2] = v2 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T2>();
}
if (instances.TryGetValue(h3, out var v3) is false)
{
instances[h3] = v3 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T3>();
}
if (instances.TryGetValue(h4, out var v4) is false)
{
instances[h4] = v4 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T4>();
}
if (instances.TryGetValue(h5, out var v5) is false)
{
instances[h5] = v5 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T5>();
}
array[i] = (Unsafe.As<T>(v0), Unsafe.As<T1>(v1), Unsafe.As<T2>(v2), Unsafe.As<T3>(v3),
Unsafe.As<T4>(v4), Unsafe.As<T5>(v5));
i++;
}
try
{
return new Span<(T, T1, T2, T3, T4, T5)>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
}
public Span<(T, T1, T2, T3, T4, T5, T6)> QueryComponents<T, T1, T2, T3, T4, T5, T6>() where T : class
where T1 : class
where T2 : class
where T3 : class
where T4 : class
where T5 : class
where T6 : class
{
var pool = ArrayPool<(T, T1, T2, T3, T4, T5, T6)>.Shared;
var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode());
var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode());
var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode());
var t3Set = _typeCaches.GetOrCreate(typeof(T3).GetHashCode());
var t4Set = _typeCaches.GetOrCreate(typeof(T4).GetHashCode());
var t5Set = _typeCaches.GetOrCreate(typeof(T5).GetHashCode());
var t6Set = _typeCaches.GetOrCreate(typeof(T6).GetHashCode());
var count = math.max(hashset.Count,
math.max(t1Set.Count,
math.max(t2Set.Count,
math.max(t3Set.Count, math.max(t4Set.Count, math.max(t5Set.Count, t6Set.Count))))));
var array = pool.Rent(count);
var collection = _pool.Take();
collection.Clear();
collection.UnionWith(hashset);
collection.IntersectWith(t1Set);
collection.IntersectWith(t2Set);
collection.IntersectWith(t3Set);
collection.IntersectWith(t4Set);
collection.IntersectWith(t5Set);
collection.IntersectWith(t6Set);
var i = 0;
foreach (var id in collection)
{
var instances = _typeInstances.GetOrCreate(id);
var h0 = typeof(T).GetHashCode();
var h1 = typeof(T1).GetHashCode();
var h2 = typeof(T2).GetHashCode();
var h3 = typeof(T3).GetHashCode();
var h4 = typeof(T4).GetHashCode();
var h5 = typeof(T5).GetHashCode();
var h6 = typeof(T6).GetHashCode();
if (instances.TryGetValue(h0, out var v0) is false)
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
if (instances.TryGetValue(h1, out var v1) is false)
{
instances[h1] = v1 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T1>();
}
if (instances.TryGetValue(h2, out var v2) is false)
{
instances[h2] = v2 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T2>();
}
if (instances.TryGetValue(h3, out var v3) is false)
{
instances[h3] = v3 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T3>();
}
if (instances.TryGetValue(h4, out var v4) is false)
{
instances[h4] = v4 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T4>();
}
if (instances.TryGetValue(h5, out var v5) is false)
{
instances[h5] = v5 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T5>();
}
if (instances.TryGetValue(h6, out var v6) is false)
{
instances[h6] = v6 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T6>();
}
array[i] = (Unsafe.As<T>(v0), Unsafe.As<T1>(v1), Unsafe.As<T2>(v2), Unsafe.As<T3>(v3),
Unsafe.As<T4>(v4), Unsafe.As<T5>(v5), Unsafe.As<T6>(v6));
i++;
}
try
{
return new Span<(T, T1, T2, T3, T4, T5, T6)>(array, 0, i);
}
finally
{
pool.Return(array);
_pool.Return(collection);
}
return list.ToArray();
}
public void Dispose()
@@ -286,14 +625,14 @@ namespace BITKit.Entities
_count--;
if (_count <= 0)
{
Entities.Clear();
_entitiesInternal.Clear();
}
_logger.LogInformation($"已释放,还剩{_count}个实例");
_cancellationTokenSource?.Dispose();
_ticker.Remove(OnTick);
_ticker?.Remove(OnTick);
}
}
}