add ModalPauseScope for the pause-around-modal idiom
Four MainWindow sites hand-rolled snapshot speed / setGameSpeed(0) / modal / restore + resetFrameTimer, with the restore duplicated on early-return paths. ModalPauseScope does it via RAII, with restore()/release() for the two sites that must restore early or not at all. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "ShipLayoutBlueprintSerializer.h"
|
||||
#include "ShipLayoutDialog.h"
|
||||
#include "ItemIconCache.h"
|
||||
#include "ModalPauseScope.h"
|
||||
#include "Simulation.h"
|
||||
#include "Tick.h"
|
||||
#include "VisualsLoader.h"
|
||||
@@ -167,8 +168,7 @@ void MainWindow::layoutPanels()
|
||||
|
||||
void MainWindow::handleEvent(std::shared_ptr<const SchematicChoicesAvailableEvent> event)
|
||||
{
|
||||
const double prevSpeed = m_gameWorldView->getGameSpeed();
|
||||
m_gameWorldView->setGameSpeed(0.0);
|
||||
ModalPauseScope pause(*m_gameWorldView);
|
||||
|
||||
ModalDimScope dim(*m_dimOverlay);
|
||||
SchematicChoiceDialog dialog(event->choices, m_sim->getConfig().recipes, this);
|
||||
@@ -179,15 +179,11 @@ void MainWindow::handleEvent(std::shared_ptr<const SchematicChoicesAvailableEven
|
||||
command->choiceIndex = dialog.getChosenIndex();
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<CommandRequestedEvent>(command));
|
||||
|
||||
m_gameWorldView->setGameSpeed(prevSpeed);
|
||||
m_gameWorldView->resetFrameTimer();
|
||||
}
|
||||
|
||||
void MainWindow::handleEvent(std::shared_ptr<const EscapeMenuRequestedEvent> /*event*/)
|
||||
{
|
||||
const double prevSpeed = m_gameWorldView->getGameSpeed();
|
||||
m_gameWorldView->setGameSpeed(0.0);
|
||||
ModalPauseScope pause(*m_gameWorldView);
|
||||
|
||||
ModalDimScope dim(*m_dimOverlay);
|
||||
QMessageBox box(this);
|
||||
@@ -204,12 +200,13 @@ void MainWindow::handleEvent(std::shared_ptr<const EscapeMenuRequestedEvent> /*e
|
||||
std::optional<GameConfig> newConfig = reloadConfig();
|
||||
if (!newConfig.has_value())
|
||||
{
|
||||
m_gameWorldView->setGameSpeed(prevSpeed);
|
||||
m_gameWorldView->resetFrameTimer();
|
||||
return;
|
||||
}
|
||||
// Restart is a command boundary; the view resets when the drain applies
|
||||
// it (see GameWorldView::onFrame). A fresh random seed starts a new run.
|
||||
// resetForNewGame() sets the speed for the new run, so the pre-restart
|
||||
// speed is deliberately not restored here.
|
||||
pause.release();
|
||||
std::shared_ptr<ResetCommand> command = std::make_shared<ResetCommand>();
|
||||
command->config = std::make_shared<GameConfig>(std::move(*newConfig));
|
||||
command->seed = std::random_device{}();
|
||||
@@ -218,13 +215,9 @@ void MainWindow::handleEvent(std::shared_ptr<const EscapeMenuRequestedEvent> /*e
|
||||
}
|
||||
else if (clicked == quitBtn)
|
||||
{
|
||||
pause.release();
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gameWorldView->setGameSpeed(prevSpeed);
|
||||
m_gameWorldView->resetFrameTimer();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<GameConfig> MainWindow::reloadConfig()
|
||||
@@ -252,8 +245,7 @@ void MainWindow::openShipLayoutDialog(BuildingId shipyardId,
|
||||
const std::string& schematicId,
|
||||
const ShipLayoutConfig& currentLayout)
|
||||
{
|
||||
const double prevSpeed = m_gameWorldView->getGameSpeed();
|
||||
m_gameWorldView->setGameSpeed(0.0);
|
||||
ModalPauseScope pause(*m_gameWorldView);
|
||||
|
||||
std::set<std::string> unlockedModuleIds;
|
||||
for (const ModuleDef& def : m_sim->getConfig().modules.modules)
|
||||
@@ -279,9 +271,6 @@ void MainWindow::openShipLayoutDialog(BuildingId shipyardId,
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<CommandRequestedEvent>(command));
|
||||
}
|
||||
|
||||
m_gameWorldView->setGameSpeed(prevSpeed);
|
||||
m_gameWorldView->resetFrameTimer();
|
||||
}
|
||||
|
||||
void MainWindow::handleEvent(std::shared_ptr<const LayoutDialogRequestedEvent> event)
|
||||
@@ -311,8 +300,7 @@ void MainWindow::handleEvent(std::shared_ptr<const LayoutDialogRequestedEvent> e
|
||||
|
||||
void MainWindow::handleEvent(std::shared_ptr<const RecipeSelectionRequestedEvent> event)
|
||||
{
|
||||
const double prevSpeed = m_gameWorldView->getGameSpeed();
|
||||
m_gameWorldView->setGameSpeed(0.0);
|
||||
ModalPauseScope pause(*m_gameWorldView);
|
||||
|
||||
// A construction site has no Building yet; fall back to its site record so
|
||||
// the recipe/schematic can be chosen before it is built (REQ-BLD-SITE-CONFIG).
|
||||
@@ -321,8 +309,6 @@ void MainWindow::handleEvent(std::shared_ptr<const RecipeSelectionRequestedEvent
|
||||
b ? nullptr : m_sim->getBuildings().findSite(event->buildingId);
|
||||
if (!b && !s)
|
||||
{
|
||||
m_gameWorldView->setGameSpeed(prevSpeed);
|
||||
m_gameWorldView->resetFrameTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -361,13 +347,11 @@ void MainWindow::handleEvent(std::shared_ptr<const RecipeSelectionRequestedEvent
|
||||
}
|
||||
}
|
||||
|
||||
m_gameWorldView->setGameSpeed(prevSpeed);
|
||||
m_gameWorldView->resetFrameTimer();
|
||||
|
||||
// The SetRecipeCommand above is queued (drains on a later frame) and clears
|
||||
// the shipyard's layout, so open the dialog with the chosen schematic and an
|
||||
// empty layout rather than reading the not-yet-updated building state. Speed
|
||||
// is already restored so the helper snapshots the real speed to restore.
|
||||
// is restored first so the helper snapshots the real speed to restore.
|
||||
pause.restore();
|
||||
if (autoOpenLayout)
|
||||
{
|
||||
openShipLayoutDialog(event->buildingId, chosenSchematic, ShipLayoutConfig{});
|
||||
|
||||
Reference in New Issue
Block a user