lundi 22 mars 2021

How to map string literals to types in C++

I'm writing a small 2D game and I'm currently adding scripting capabilities to it (using Lua or Python), and I stumbled on this problem (which I think will lead me to implement some kind of reflection system for my game):

I'm using the Entity Component System pattern, and the definition for an entity is provided by a script (a Lua table or a Python dict), so whenever I want to construct an entity I run the script:

player = {
     transformComponent = { 
            position = {1.0, 2.0, 0.0},
            scale = {1.0, 2.0, 1.0}
     },
     spriteComponent = {
            fileName = 'imageFile.png',
            numRows = 4,
            numCols = 6
     }
}

and so on. In an EntityFactory I have a map of EntityFactoryFunctions, keyed by the name of the entity (e.g. 'Player'), and I call them when I need to construct such named entity.

Now, each factory function will read the table (dict) of the entity and get all the names of the components it needs to add to the entity.

Entity *CreateEntity(const std::string entityType) // table / dictionary name in script
{
    Entity *newEntity = Scene::GetInstance().AddEntity();
        
    return mEntityFactories[entityType](newEntity);
}

typedef Entity *(*EntityFactoryFunction)(Entity*);
std::map<std::string, EntityFactoryFunction> mEntityFactories;

Problem is, my ECS uses a function of the type enity.AddComponent<COMPONENT_TYPE>():

Entity *PlayerFactory(Entity *entity)
{
    // read components from Lua table / Python dictionary
    // get strings of components' names and store them into vector
    Vector<std::string> componentNames;

    // create components and add to entity
    for (const auto &componentName : componentNames)
    {
        Component *component = mComponentFactories[componentName](/* pass a reference to component table / dictionary */);
        entity->AddComponent<......>(component);  // I must know the component type
    }

    return entity;
}

How can I get the name of the component to pass to the function template? Do I need some kind of reflection system?





Aucun commentaire:

Enregistrer un commentaire