Files
riversong-code-showcase/Source/Riversong/Game/CommonServices/Entities/EntityCollection.cs
2026-05-21 16:04:49 +02:00

90 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class EntityCollection : IEntityCollection
{
private static readonly List<Entity> Empty = new();
private int _nextId = Entity.InvalidId + 1;
private Dictionary<int, Entity> _entitiesById = new();
private ListMultiDictionary<Type, Entity> _entitiesByType = new();
private Dictionary<Type, IEntityCollectionCallbacks> _callbacks = new();
public T Create<T>() where T : Entity, new()
{
return Entity.Create<T>(_nextId++);
}
public void Add(Entity entity)
{
_entitiesById.Add(entity.Id, entity);
OnAdded(entity.GetType(), entity);
}
private void OnAdded(Type type, Entity entity)
{
_entitiesByType.Add(type, entity);
if (_callbacks.TryGetValue(type, out var callbacks)) callbacks.OnAdded(entity);
if (type == typeof(Entity)) return;
OnAdded(type.BaseType, entity);
}
public Entity Remove(int id)
{
if (!_entitiesById.Remove(id, out var entity)) return null;
OnRemoved(entity.GetType(), entity);
return entity;
}
private void OnRemoved(Type type, Entity entity)
{
_entitiesByType.Remove(type, entity);
if (_callbacks.TryGetValue(type, out var callbacks)) callbacks.OnRemoved(entity);
if (type == typeof(Entity)) return;
OnRemoved(type.BaseType, entity);
}
public bool Exists(int id)
{
return _entitiesById.ContainsKey(id);
}
public Entity Get(int id)
{
return _entitiesById.TryGetValue(id, out var entity) ? entity : null;
}
public Type GetEntityType(int id)
{
return Get(id)?.GetType();
}
public List<Entity> GetInternalEntityList(Type type)
{
return _entitiesByType.TryGetValues(type, out var entityList) ? entityList : Empty;
}
public IEntityCollectionCallbacks<T> On<T>() where T : Entity
{
if (!_callbacks.TryGetValue(typeof(T), out var callbacks))
{
callbacks = new EntityCollectionCallbacks<T>();
_callbacks.Add(typeof(T), callbacks);
}
return (IEntityCollectionCallbacks<T>)callbacks;
}
}
}