#pragma once #include "GameWorldView.h" // RAII guard for the "pause the game while a modal is open" idiom (REQ-UI-SPEED). // Constructing it snapshots the current game speed and pauses the game; on scope // exit it restores the snapshotted speed and rebases the render frame timer, so the // wall time the player spent in the dialog is not converted into simulation ticks. // // Pairs with ModalDimScope, which the same call sites use for the dim overlay. // // Two escape hatches for the paths that must not simply restore at scope exit: // restore() — restore now instead of at scope exit, for when more work has to run // at the player's real speed before the scope ends (e.g. a follow-up // dialog that snapshots the speed itself). // release() — abandon the restore entirely, for when the game is about to be // reset or the window closed and the old speed is meaningless. // Both are idempotent and the destructor does nothing once either has run. class ModalPauseScope { public: explicit ModalPauseScope(GameWorldView& view) : m_view(view) , m_previousGameSpeed(view.getGameSpeed()) , m_restorePending(true) { m_view.setGameSpeed(0.0); } ~ModalPauseScope() { restore(); } void restore() { if (!m_restorePending) { return; } m_restorePending = false; m_view.setGameSpeed(m_previousGameSpeed); m_view.resetFrameTimer(); } void release() { m_restorePending = false; } ModalPauseScope(const ModalPauseScope&) = delete; ModalPauseScope& operator=(const ModalPauseScope&) = delete; private: GameWorldView& m_view; double m_previousGameSpeed; bool m_restorePending; };