using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Security.AccessControl; using System.Threading; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace BITKit.Entities { public class EntitiesService:IEntitiesService,IDisposable { private readonly ILogger _logger; private static int _count; public EntitiesService() { _count++; } public EntitiesService(ILogger logger) { _count++; _logger = logger; } private static readonly ConcurrentDictionary Entities = new(); public event Action OnAdd; public event Action OnRemove; IEntity[] IEntitiesService.Entities => Entities.Values.ToArray(); public bool Register(IEntity entity) { if (!Entities.TryAdd(entity.Id, entity)) return false; OnAdd?.Invoke(entity); return true; } public bool UnRegister(IEntity entity) { if (!Entities.TryRemove(entity.Id, out _)) return false; OnRemove?.Invoke(entity); return true; } public CancellationToken CancellationToken => _cancellationTokenSource.Token; private readonly CancellationTokenSource _cancellationTokenSource = new(); public IEntity Get(int id) { return Entities[id]; } public bool TryGetEntity(int id, out IEntity entity) { return Entities.TryGetValue(id, out entity); } public IEntity GetOrAdd(int id, Func factory) { return Entities.GetOrAdd(id, factory); } public IEntity[] Query() { throw new NotImplementedException("Obsoleted"); } public T[] QueryComponents() { var list = new List(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1) { list.Add(t1); } } return list.ToArray(); // return _queryCache.GetOrAdd(typeof(T), type => // { // return _entities.Values.Where(entity => entity.TryGetComponent(out T component)).ToArray(); // }).Cast().ToArray(); } public (T, T1)[] QueryComponents() { var list = new List<(T, T1)>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() 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() { var list = new List<(T, T1, T2)>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() is { } t2 && entity.ServiceProvider.GetService() 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(); } public (T, T1, T2, T3)[] QueryComponents() { var list = new List<(T, T1, T2, T3)>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() is { } t2 && entity.ServiceProvider.GetService() is { } t3 && entity.ServiceProvider.GetService() 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(); } public (T, T1, T2, T3, T4)[] QueryComponents() { var list = new List<(T, T1, T2, T3, T4)>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() is { } t2 && entity.ServiceProvider.GetService() is { } t3 && entity.ServiceProvider.GetService() is { } t4 && entity.ServiceProvider.GetService() 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(); } public (T, T1, T2, T3, T4, T5)[] QueryComponents() { var list = new List<(T, T1, T2, T3, T4, T5)>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() is { } t2 && entity.ServiceProvider.GetService() is { } t3 && entity.ServiceProvider.GetService() is { } t4 && entity.ServiceProvider.GetService() is { } t5 && entity.ServiceProvider.GetService() 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(); } public (T, T1, T2, T3, T4, T5, T6)[] QueryComponents() { var list = new List<(T, T1, T2, T3, T4, T5, T6)>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() is { } t2 && entity.ServiceProvider.GetService() is { } t3 && entity.ServiceProvider.GetService() is { } t4 && entity.ServiceProvider.GetService() is { } t5 && entity.ServiceProvider.GetService() is { } t6 && entity.ServiceProvider.GetService() is { } t7) { list.Add((t1, t2, t3, t4, t5, t6, t7)); } } 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(); } public ValueTuple[] QueryComponents() where TRest : struct { var list = new List>(); foreach (var entity in Entities.Values) { if (entity.ServiceProvider.GetService() is { } t1 && entity.ServiceProvider.GetService() is { } t2 && entity.ServiceProvider.GetService() is { } t3 && entity.ServiceProvider.GetService() is { } t4 && entity.ServiceProvider.GetService() is { } t5 && entity.ServiceProvider.GetService() is { } t6 && entity.ServiceProvider.GetService() is { } t7 && entity.ServiceProvider.GetService() is { } t8) { list.Add(new ValueTuple(t1, t2, t3, t4, t5, t6, t7, t8)); } } return list.ToArray(); } public void Dispose() { _count--; if (_count <= 0) { Entities.Clear(); } _logger.LogInformation($"已释放,还剩{_count}个实例"); _cancellationTokenSource?.Dispose(); } } }