Присвойте конкретный глобальный индекс данному объекту на основе его типа (C #) - PullRequest
0 голосов
/ 27 февраля 2019

Я играл с несколькими простыми игровыми программами на C #, используя моногаму, и в настоящее время я пытаюсь создать элементарный ECS с нуля.Я понимаю, что уже существуют очень хорошо сделанные библиотеки ECS, это больше личное упражнение.

Код, который у меня есть на данный момент, выглядит примерно так:

public class Entity{

    private bool active;
    IComponent[] Components;
    public Entity(){
        active = true;

    }

    public AddComponent(IComponent component){

    }


    public bool Active { get => active; set => active = value; }
}

С IComponent являетсяинтерфейс для компонентов, и мне было интересно, существует ли способ определения индекса глобального массива для определенного типа компонента, когда он впервые определен во время выполнения?

Как, например;Если у вас есть Transform Component и CollisionComponent, то, когда первый компонент Transform во время выполнения определен, глобальный индекс присваивается каждому компоненту Transform, определенному после, с компонентом коллайдера, который ведет себя аналогичным образом, но с явно другим номером индекса.

C ++ эквивалент того, что я ищу, выглядит примерно так:

inline ComponentID getNewComponentTypeID()
{
    static ComponentID lastID = 0u;
    return lastID++;
}

template <typename T>
inline ComponentID getComponentTypeID() noexcept
{
    static_assert(std::is_base_of<Component, T>::value, "");
    static ComponentID typeID = getNewComponentTypeID();
    return typeID;
}

1 Ответ

0 голосов
/ 27 февраля 2019

Обновление: Заменено на лучшее решение, включающее инициализацию статического свойства.


Если вам нужно отслеживать типы компонентов, вы можете сделать это с помощью инициализации статического поля.Это будет выглядеть так:

static class ComponentId
{
    static int Max = 0;
    static class Index<T> where T: IComponent
    {
        public static int Value = Interlocked.Increment(ref Max);
    }
    static public int Get<T>() where T : IComponent => Index<T>.Value;
}

Использование:

var id1 = ComponentId.Get<TransformComponent>() // 1
var id1 = ComponentId.Get<CollisionComponent>() // 2
var id3 = ComponentId.Get<TransformComponent>() // again 1

Старый ответ: Для случая, когда вам нужен рабочий индекс внутри каждогокомпонента, вы можете сделать следующее:

static class GlobalCounter<T> where T : IComponent
{
    static int Value = 0;
    static public int GetNext() => Interlocked.Increment(ref Value);
}

Вы можете использовать его следующим образом: GlobalCounter<TransformComponent>.GetNext().Там будет отдельный Value для каждого T.

...