简体   繁体   English

C ++实施状态

[英]C++ Implementing states

My question is: I am trying to implement basic state management in my project and i stuck at changing states. 我的问题是:我正在尝试在项目中实施基本状态管理,而我却坚持更改状态。 I have all my states in std::stack<State*> container, and push/pop them directly from Application class or from State class. 我将所有状态存储在std::stack<State*>容器中,并直接从Application类或State类推送/弹出它们。 Problem is when i change current state from State class, it can be destroyed before render method called, whitch results in exeption. 问题是,当我从State类更改当前状态时,可以在调用render方法之前将其销毁,从而导致异常。 So how do i avoid this? 那么我该如何避免呢? PS sorry for my english and please say me if something in my problem/code isn clear PS对不起我的英语,如果我的问题/代码中的某些内容不清楚,请告诉我

Application class: 应用类别:

void Application::pushState(State* state)
{
    this->m_states.push(state);
    this->m_states.top()->open();//enter state
}

void Application::popState()
{
    if (!this->m_states.empty())
    {
        this->m_states.top()->close();//leave state
        delete this->m_states.top();
    }

    if (!this->m_states.empty())
    this->m_states.pop();
}

void Application::changeState(State* state)
{
    if (!this->m_states.empty())
        popState();
    pushState(state);
}

State* Application::peekState()
{
    if (this->m_states.empty()) return nullptr;
    return this->m_states.top();
}

void Application::mainLoop()
{
    sf::Clock clock;

    while (this->m_window.isOpen())
    {
        sf::Time elapsed = clock.restart();
        float delta = elapsed.asSeconds();

        if (this->peekState() == nullptr)
            this->m_window.close();
        this->peekState()->update(delta)//if i change state in State.update(), it may be that code below will now point to not existing state

        if (this->peekState() == nullptr)
            this->m_window.close();
        this->peekState()->render(delta);
    }
}

State class: 州级:

void EditorState::update(const float delta)
{
    sf::Event event;
    while (this->m_application->m_window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
        {
            this->m_application->popState();
            return;
        }
    }
}

Okay maybe this is not really a problem, but something like "how to" question. 好的,也许这并不是一个真正的问题,而是类似“如何”的问题。 As you can see in my code, i update and render states in mainLoop() method. 如您在我的代码中看到的,我在mainLoop()方法中更新和呈现状态。 What im tying to figure out is how to manage those updates, asuming that state can be changed from state itself, not only from stateManager (in my case Application class) 要弄清楚的是如何管理这些更新,假设状态可以从状态本身更改,而不仅仅是从stateManager(在我的情况下为Application类)更改。

Ok, so I'm guessing this is for a game (but it doesn't have to be). 好的,所以我猜测这是针对游戏的(但不一定如此)。 Instead of doing what you're doing for switching between states, I use an enum. 我使用枚举代替执行您在状态之间切换所要做的事情。

enum class GameState {
    MENU, PLAY, PAUSE
}

Then, in your main header 然后,在您的主标题中

GameState m_gameState = GameState::MENU;

In your main loop, you can check what the current state is by simply doing 在主循环中,只需执行以下操作即可检查当前状态

if (m_gameState == GameState::MENU)
{
    ...
}

or you can use a switch statement 或者您可以使用switch语句

switch (m_gameState)
{
case GameState::MENU:
    ...
    break;
case GameState::PLAY:
    ...
    break;
case GameState::PAUSE:
    ...
    break;
}

And, if you ever want to switch the state, you can just do 而且,如果您要切换状态,则只需执行

m_gameState = GameState::PAUSE;

Hope this answered your question :D 希望这回答了您的问题:D

If not, I must have misunderstood (sorry). 如果没有,我一定会误会(抱歉)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM