cxx之简单的状态转换模型

260 阅读1分钟
class AuthDelegate {

public:
    AuthDelegate() : m_state(State::INIT), m_stopping(false) {
        m_loop_thread = std::thread(&AuthDelegate::mainLoop, this);
    }

    ~AuthDelegate() {
        std::cout << "~AuthDelegate" << std::endl;
        if (m_loop_thread.joinable()) {
            m_loop_thread.join();
        }
    }

private:
    enum class State {
        INIT,
        AUTHORIZING,
        CONNECTING,
        CONNECTED,
        SHUTDOWN
    };

    const static char* state2Str(const State state) {
        switch (state) {
            case State::INIT:
                return "INIT";
            case State::AUTHORIZING:
                return "AUTHORIZING";
            case State::CONNECTING:
                return "CONNECTING";
            case State::CONNECTED:
                return "CONNECTED";
            case State::SHUTDOWN:
                return "SHUTDOWN";
            default: {
                return "UNKNOWN";
            }
        }
    }

    void mainLoop() {
        while (!isStopping()) {
            sleep(1);
            State nextState = getState();
            std::cout << "nextState->" << state2Str(nextState) << std::endl;
            switch (nextState) {
                case State::INIT:
                    handleInit();
                    break;
                case State::AUTHORIZING:
                    handleAuthorizing();
                    break;
                case State::CONNECTING:
                    handleConnecting();
                    break;
                case State::CONNECTED:
                    handleConnected();
                    break;
                case State::SHUTDOWN:
                    handleShutdown();
                    break;
            }
            setState(m_state);
        }
    }

    void handleInit() {
        setState(State::AUTHORIZING);
    }

    void handleAuthorizing() {
        setState(State::CONNECTING);
    }

    void handleConnecting() {
        setState(State::CONNECTED);
    }

    void handleConnected() {
        sendMessage(m_state);
    }

    void handleShutdown() {
        setState(State::SHUTDOWN);
    }

    void sendMessage(State while_state) {
        {
            std::unique_lock<std::mutex> lock(m_state_mutex);
            // 如果while_state和m_state一样就需要阻塞,否则不需要阻塞
            m_state_cv.wait(lock, [this, &while_state] {
                return while_state != m_state;
            });
        }
        setState(while_state);
    }

    void setState(State state) {
        std::lock_guard<std::mutex> lock(m_state_mutex);
        m_state = state;
    }

    State getState() {
        std::lock_guard<std::mutex> lock(m_state_mutex);
        return m_state;
    }

    bool isStopping() {
        std::lock_guard<std::mutex> lock(m_stopping_mutex);
        return m_stopping;
    }

private:
    std::mutex m_state_mutex;
    std::condition_variable m_state_cv;
    State m_state;

    std::mutex m_stopping_mutex;
    bool m_stopping;

    std::thread m_loop_thread;
};