#pragma once

#define REGISTRABLE(c)        \
                              \
public:                       \
    static const c* INSTANCE; \
    static const int ID;      \
                              \
private:

#define REGISTER(c, typ)

template<typename T> class StaticRegistry
{
private:
    T** registry;
    int count;

public:
    StaticRegistry()
    {
        count = 1;
        registry = new T*[count];
        memset(registry, 0, sizeof(T*) * count);
    }

    ~StaticRegistry()
    {
        for (int index = 0; index < count; index++)
        {
            if (registry[index])
            {
                registry[index]->release();
                registry[index] = 0;
            }
        }
        delete[] registry;
    }

    void registerT(T* type, int id)
    {
        if (id >= count)
        {
            T** temp = new T*[id + 1];
            memcpy(temp, registry, sizeof(T*) * count);
            memset(temp + count, 0, sizeof(T*) * (id + 1 - count));
            delete[] registry;
            registry = temp;
            count = id + 1;
        }
        registry[id] = type;
    }

    T* zElement(int id)
    {
        if (id < 0 || id >= count) return 0;
        return registry[id];
    }

    int getCount() const
    {
        return count;
    }

    friend T;
};