Как вести реестр функций переменных параметров - PullRequest
1 голос
/ 21 октября 2011

Я объясню, что я пытаюсь сделать:

Я работаю над игрой.Для работы с графикой у меня есть стек экранных слоев, который я обновляю и рисую.ScreenLayer отвечает за предоставление визуализации для некоторого аспекта игры (инвентарь, обзор партии, карта мира, карта тайлов и т. Д.)

Для обработки переходов экрана я хочу создать реестр функций дляразличные типы экранов, и затем экраны будут вызываться в этот реестр, чтобы выдвигать и выталкивать слои экрана из стека отрисовки.(т. е. когда вы нажимаете старт на карте тайлов, карта тайлов вызовет реестр и скажет ему создать экран корневого меню пуска. Начальное меню будет перенесено поверх карты тайлов и получит контроль над вводомдо тех пор, пока меню «Пуск» не будет закрыто, и в этот момент оно покидает стек и возвращает управление слою, который его вызвал)

Проблема заключается в том, что для создания каждого слоя экрана необходим свой набор параметров

т.е.

CharacterOverviewScreen(boost::shared_ptr<Engine>& engine, const std::string& rmlDoc, Game::Character::Party* party);

против

MapViewLayer(boost::shared_ptr<Engine>& engine, const std::string &mapFile, const sf::Vector2f &startPos, const std::string &name, int layerID, bool draw, Game::Character::Party* party);

В идеале я бы хотел, чтобы на каждом экране была возможность зарегистрировать небольшую функцию, которая оборачивает мой слой экрана и превращает его вправильный ScreenStack

т.е.

ScreenStack CharacterOverviewStackCreator(boost::shared_ptr<Engine>& engine, const std::string& stackName const std::string& rmlDoc, Game::Character::Party* party)
{
    return ScreenStack(stackName, engine->GetUID(), boost:shared_ptr<ScreenLayer>(new CharacterOverviewScreen(engine, rmlDoc, party)));
}

Мне нужен способ регистрации функций создания ScreenStack, которые принимают переменные параметры и, если это вообще возможно, чтобы каждый производный класс ScreenLayer мог зарегистрировать создание этого стекафункционировать сам.

Моей первоначальной мыслью было попробовать что-то вроде этого:

typedef boost::function<ScreenStack (boost::shared_ptr<Engine>& engine, const std::string stackName, ...)> ScreenCreationFunction;

class ScreenManager : public AnimatedDraw
{
public:
    ScreenManager(boost::shared_ptr<Engine>& engine);
    bool RegisterScreenMakerFunction(const ScreenCreationFunction& creatorFunction, bool overwriteExisting = false);
    ScreenCreationFunction& GetScreenMakerFunction(const std::string& makerName);

    ScreenStack MakeStack(const std::string& makerFunction, const std::string, const std::vector<std::string>& TryToCopyStacks, ...);

protected:
private:
    boost::shared_ptr<Engine> engine;
    boost::unordered_map<std::string, ScreenCreationFunction> ScreenMakerFunctions;
};

Однако boost :: function не работает с "..." из <cstdarg>.Кроме того, у меня нет возможности предварительно зарегистрировать экраны, прежде чем я попытаюсь их создать.

Я подумал о переключении на некий универсальный указатель на функцию void над boost :: function, но если я могу избежать этого, я бы хотел.Я думаю, что это возможно сделать регистрацию стека с помощью препроцессора, но у меня нет большого опыта с препроцессором, поэтому я понятия не имею, как это сделать.

Я думал об использовании фабрики для созданиястек экрана, но мне придется постоянно обновлять заводские функции, так как я добавляю все больше и больше типов слоев экрана и различных параметров, так что это не кажется очень хорошим решением.

Если кто-то может мне помочь сэто, было бы очень признательно.Если мне что-то неясно, дайте мне знать

...