Реализуете шаблон наблюдателя C++ -to-lua?

У меня есть шаблон наблюдателя (или "слушателя"), реализованный в моем коде как таковой:

struct EntityListener
{
public:
    virtual void entityModified(Entity& e) = 0;
};

class Entity
{
public:
    Entity();
    void setListener(EntityListener* listener);
private:
    EntityListener* m_listener;
};

Теперь это работает в C++; класс Entity вызывает entityModified() метод всякий раз, когда это необходимо. Теперь я хотел бы перенести некоторые функциональные возможности в Lua, и среди этих функциональных точек есть этот обратный вызов слушателя. Объекты теперь создаются из сценариев Lua. Вопрос в том, как мне достичь функциональности слушателя в Lua?

Например, скрипт Lua в настоящее время делает что-то вроде этого:

function initializeEntity()
    -- The entity object is actually created in C++ by the helper
    Entity = Helper.createEntity()

    -- Here I'd like to hook a Lua function as the Entity's listener
end

1 ответ

Решение

Одним из возможных решений является наличие LuaListener класс в вашем C++ коде, который содержит "указатель" на функцию Lua и специфичный для Lua setListener функция, которая вызывается из сценария Lua, который принимает функцию Lua в качестве аргумента и создает LuaListener экземпляр и передает это фактическому C++ setListener,


Таким образом, код Lua будет выглядеть примерно так

function onModified(entity)
  -- ...
end

function initializeEntity()
    entity = Helper.createEntity()
    entity.setListener(onModified)
end

И код C++ будет выглядеть примерно так (только псевдо-код):

class LuaListener : public EntityListener
{
private:
    lua_State* state;
    std::string funcName;

public:
    void entityModified(Entity& e)
    {
        // Call function `funcName` in `state`, passing `e` as argument
    }
};

class LuaEntity : public Entity
{
public:
    void setListenerLua(state, funcName, ...)
    {
        Entity::setListener(new LuaListener(state, funcName, ...));
    }
};
Другие вопросы по тегам