Я хочу создать пример Entity-Component-System.У меня есть такие компоненты, как
internal struct Position : IComponent
{
public int X { get; set; }
public int Y { get; set; }
}
и
internal struct Movementspeed : IComponent
{
public float Value { get; set; }
}
, которые реализуют
internal interface IComponent
{
}
При циклическом просмотре компонентов я хочу найти их как можно быстрее.Я думал о создании словаря, который принимает тип компонентов в качестве ключа и компонент в качестве значения.
internal class ComponentCollection
{
public ComponentCollection()
{
components = new Dictionary<Type, object>();
}
private Dictionary<Type, object> components;
public void AddComponent<T>(T component) // add a new component
{
Type componentType = typeof(T);
components.Add(componentType, component as IComponent);
}
public void RemoveComponent(Type componentType) // remove the component by type
{
components.Remove(componentType);
}
public bool TryGetComponent<T>(out T component) // get the specified component
{
try
{
Type componentType = typeof(T);
component = (T)components[componentType];
return true;
}
catch (Exception)
{
component = default(T);
return false;
}
}
}
Возникают две проблемы.
Чтоесли кто-то создает новый MovementspeedComponent, используя float movementspeed
, и пытается добавить его?Наличие двух чисел с плавающей точкой приведет к исключению дублированного ключаЯ мог бы только добавить пользовательские компоненты структуры, которые реализуют интерфейс IComponent
для предотвращения дублирования.
Когда я пытаюсь изменить компоненты, они не изменяются по ссылке
private static void Main(string[] args)
{
ComponentCollection components = new ComponentCollection();
components.AddComponent(new Position());
components.AddComponent(new Movementspeed());
if (components.TryGetComponent(out Position fooPosition))
{
fooPosition.X++;
Console.WriteLine(fooPosition.X); // prints 1
}
if (components.TryGetComponent(out Position barPosition))
{
Console.WriteLine(barPosition.X); // prints 0
}
Console.ReadLine();
}
Есть предложения?