Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 65 additions & 64 deletions src/application/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "application/ScenarioResultWidget.h"
#include "application/ScenarioRunWidget.h"
#include "domain/DemoFixtureService.h"
#include "domain/DemoLayouts.h"
#include "domain/DxfImportService.h"
#include "domain/ImportIssue.h"
#include "domain/ImportOrchestrator.h"
Expand Down Expand Up @@ -53,15 +52,7 @@ ProjectWorkspaceState makeEvacuationScenarioDemoWorkspace() {
using namespace safecrowd::domain;

safecrowd::domain::DemoFixtureService fixtureService;
const auto fixture = fixtureService.createSprint1DemoFixture();

auto alternative = duplicateScenarioDraft(fixture.baselineScenario, "scenario-2", "Doorway blocked alternative");
alternative.control.connectionBlocks.push_back({
.id = "block-1",
.connectionId = DemoLayouts::Sprint1FacilityIds::DoorwayConnectionId,
.intervals = {{0.0, 60.0}},
});
alternative.variationDiffKeys = computeScenarioDiffKeys(fixture.baselineScenario, alternative);
auto fixture = fixtureService.createSprint1BlockedDoorResultFixture();

SavedScenarioAuthoringState authoring;
authoring.scenarios.push_back({
Expand All @@ -70,68 +61,23 @@ ProjectWorkspaceState makeEvacuationScenarioDemoWorkspace() {
.stagedForRun = true,
});
authoring.scenarios.push_back({
.draft = alternative,
.draft = fixture.alternativeScenario,
.baseScenarioId = fixture.baselineScenario.scenarioId,
.stagedForRun = true,
});
authoring.currentScenarioIndex = 1;
authoring.navigationView = SavedNavigationView::Events;
authoring.rightPanelMode = SavedRightPanelMode::Scenario;

SimulationFrame resultFrame;
resultFrame.elapsedSeconds = 96.0;
resultFrame.complete = true;
resultFrame.totalAgentCount = 100;
resultFrame.evacuatedAgentCount = 100;

ScenarioResultArtifacts artifacts;
artifacts.evacuationProgress = {
{.timeSeconds = 0.0, .evacuatedCount = 0, .totalCount = 100, .evacuatedRatio = 0.0},
{.timeSeconds = 30.0, .evacuatedCount = 24, .totalCount = 100, .evacuatedRatio = 0.24},
{.timeSeconds = 60.0, .evacuatedCount = 72, .totalCount = 100, .evacuatedRatio = 0.72},
{.timeSeconds = 96.0, .evacuatedCount = 100, .totalCount = 100, .evacuatedRatio = 1.0},
};
artifacts.replayFrames = {resultFrame};
artifacts.timingSummary.t50Seconds = 48.0;
artifacts.timingSummary.t90Seconds = 82.0;
artifacts.timingSummary.t95Seconds = 90.0;
artifacts.timingSummary.finalEvacuationTimeSeconds = 96.0;
artifacts.timingSummary.targetTimeSeconds = alternative.execution.timeLimitSeconds;
artifacts.timingSummary.marginSeconds = alternative.execution.timeLimitSeconds - 96.0;
artifacts.exitUsage.push_back({
.exitZoneId = DemoLayouts::Sprint1FacilityIds::ExitZoneId,
.exitLabel = "Primary exit",
.floorId = DemoLayouts::Sprint1FacilityIds::FloorId,
.evacuatedCount = 100,
.usageRatio = 1.0,
.lastExitTimeSeconds = 96.0,
});
artifacts.zoneCompletion.push_back({
.zoneId = DemoLayouts::Sprint1FacilityIds::MainRoomZoneId,
.zoneLabel = "Main room",
.floorId = DemoLayouts::Sprint1FacilityIds::FloorId,
.initialCount = 100,
.evacuatedCount = 100,
.lastCompletionTimeSeconds = 96.0,
});
artifacts.placementCompletion.push_back({
.placementId = "placement-1",
.zoneId = DemoLayouts::Sprint1FacilityIds::MainRoomZoneId,
.floorId = DemoLayouts::Sprint1FacilityIds::FloorId,
.initialCount = 100,
.evacuatedCount = 100,
.lastCompletionTimeSeconds = 96.0,
});

ProjectWorkspaceState workspace;
workspace.activeView = ProjectWorkspaceView::ScenarioResult;
workspace.authoring = std::move(authoring);
workspace.runningScenario = alternative;
workspace.runningScenario = fixture.alternativeScenario;
workspace.result = SavedScenarioResultState{
.scenario = std::move(alternative),
.frame = resultFrame,
.risk = {},
.artifacts = std::move(artifacts),
.scenario = std::move(fixture.alternativeScenario),
.frame = std::move(fixture.frame),
.risk = std::move(fixture.risk),
.artifacts = std::move(fixture.artifacts),
};
return workspace;
}
Expand Down Expand Up @@ -221,6 +167,30 @@ ScenarioAuthoringWidget::RightPanelMode rightPanelModeFromSaved(SavedRightPanelM
}
}

SavedNavigationView savedNavigationViewFromInitial(ScenarioAuthoringWidget::NavigationView view) {
switch (view) {
case ScenarioAuthoringWidget::NavigationView::Crowd:
return SavedNavigationView::Crowd;
case ScenarioAuthoringWidget::NavigationView::Events:
return SavedNavigationView::Events;
case ScenarioAuthoringWidget::NavigationView::Layout:
default:
return SavedNavigationView::Layout;
}
}

SavedRightPanelMode savedRightPanelModeFromInitial(ScenarioAuthoringWidget::RightPanelMode mode) {
switch (mode) {
case ScenarioAuthoringWidget::RightPanelMode::None:
return SavedRightPanelMode::None;
case ScenarioAuthoringWidget::RightPanelMode::Run:
return SavedRightPanelMode::Run;
case ScenarioAuthoringWidget::RightPanelMode::Scenario:
default:
return SavedRightPanelMode::Scenario;
}
}

ScenarioAuthoringWidget::ScenarioState scenarioStateFromSaved(
const SavedScenarioState& saved,
const safecrowd::domain::FacilityLayout2D& layout) {
Expand Down Expand Up @@ -274,6 +244,24 @@ ScenarioAuthoringWidget::InitialState initialStateFromSaved(
return initial;
}

SavedScenarioAuthoringState savedStateFromInitial(const ScenarioAuthoringWidget::InitialState& initial) {
SavedScenarioAuthoringState saved;
saved.currentScenarioIndex = initial.currentScenarioIndex;
saved.navigationView = savedNavigationViewFromInitial(initial.navigationView);
saved.rightPanelMode = savedRightPanelModeFromInitial(initial.rightPanelMode);
saved.scenarios.reserve(initial.scenarios.size());
for (const auto& scenario : initial.scenarios) {
auto draft = scenario.draft;
draft.control.events = scenario.events;
saved.scenarios.push_back({
.draft = std::move(draft),
.baseScenarioId = scenario.baseScenarioId.toStdString(),
.stagedForRun = scenario.stagedForRun,
});
}
return saved;
}

template <typename Widget>
Widget* visibleChild(QWidget* root) {
if (root == nullptr) {
Expand Down Expand Up @@ -423,7 +411,12 @@ void MainWindow::openProject(const ProjectMetadata& metadata) {
break;
case ProjectWorkspaceView::ScenarioRun:
if (workspace.runningScenario.has_value()) {
showScenarioRun(*importResult.layout, *workspace.runningScenario);
showScenarioRun(
*importResult.layout,
*workspace.runningScenario,
workspace.authoring.has_value()
? std::make_optional(initialStateFromSaved(*workspace.authoring, *importResult.layout))
: std::nullopt);
return;
}
break;
Expand Down Expand Up @@ -486,6 +479,9 @@ void MainWindow::saveCurrentProject() {
workspace.authoring = authoringWidget->currentSavedState();
} else if (auto* resultWidget = visibleChild<ScenarioResultWidget>(centralWidget())) {
workspace.activeView = ProjectWorkspaceView::ScenarioResult;
if (resultWidget->returnAuthoringState().has_value()) {
workspace.authoring = savedStateFromInitial(*resultWidget->returnAuthoringState());
}
workspace.result = SavedScenarioResultState{
.scenario = resultWidget->scenario(),
.frame = resultWidget->frame(),
Expand All @@ -494,6 +490,9 @@ void MainWindow::saveCurrentProject() {
};
} else if (auto* runWidget = visibleChild<ScenarioRunWidget>(centralWidget())) {
workspace.activeView = ProjectWorkspaceView::ScenarioRun;
if (runWidget->returnAuthoringState().has_value()) {
workspace.authoring = savedStateFromInitial(*runWidget->returnAuthoringState());
}
workspace.runningScenario = runWidget->scenario();
}

Expand Down Expand Up @@ -602,7 +601,8 @@ void MainWindow::showScenarioAuthoring(

void MainWindow::showScenarioRun(
const safecrowd::domain::FacilityLayout2D& layout,
const safecrowd::domain::ScenarioDraft& scenario) {
const safecrowd::domain::ScenarioDraft& scenario,
std::optional<ScenarioAuthoringWidget::InitialState> returnAuthoringState) {
setCentralWidget(new ScenarioRunWidget(
currentProject_.name,
layout,
Expand All @@ -622,7 +622,8 @@ void MainWindow::showScenarioRun(
showLayoutReview(currentProject_);
}
},
this));
this,
std::move(returnAuthoringState)));
}

void MainWindow::showScenarioResult(
Expand Down
3 changes: 2 additions & 1 deletion src/application/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class MainWindow : public QMainWindow {
ScenarioAuthoringWidget::InitialState initialState);
void showScenarioRun(
const safecrowd::domain::FacilityLayout2D& layout,
const safecrowd::domain::ScenarioDraft& scenario);
const safecrowd::domain::ScenarioDraft& scenario,
std::optional<ScenarioAuthoringWidget::InitialState> returnAuthoringState = std::nullopt);
void showScenarioResult(
const safecrowd::domain::FacilityLayout2D& layout,
const safecrowd::domain::ScenarioDraft& scenario,
Expand Down
18 changes: 17 additions & 1 deletion src/application/ScenarioAuthoringWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,21 @@ SavedScenarioAuthoringState ScenarioAuthoringWidget::currentSavedState() const {
return state;
}

ScenarioAuthoringWidget::InitialState ScenarioAuthoringWidget::currentInitialState() const {
InitialState state;
state.currentScenarioIndex = currentScenarioIndex_;
state.navigationView = navigationView_;
state.rightPanelMode = rightPanelMode_;
state.scenarios.reserve(scenarios_.size());
for (const auto& scenario : scenarios_) {
auto copy = scenario;
copy.draft.control.events = copy.events;
copy.stagedForRun = copy.stagedForRun && scenarioHasOccupants(copy);
state.scenarios.push_back(std::move(copy));
}
return state;
}

void ScenarioAuthoringWidget::addEventDraft(const QString& name, const QString& trigger, const QString& target) {
auto* scenario = currentScenario();
if (scenario == nullptr) {
Expand Down Expand Up @@ -1067,7 +1082,8 @@ void ScenarioAuthoringWidget::runFirstStagedBaselineScenario() {
saveProjectHandler_,
openProjectHandler_,
backToLayoutReviewHandler_,
this);
this,
currentInitialState());
rootLayout->replaceWidget(shell_, runWidget);
shell_->hide();
shell_->deleteLater();
Expand Down
1 change: 1 addition & 0 deletions src/application/ScenarioAuthoringWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class ScenarioAuthoringWidget : public QWidget {
QWidget* parent = nullptr);

SavedScenarioAuthoringState currentSavedState() const;
InitialState currentInitialState() const;

private:
void initializeUi(bool promptForScenario);
Expand Down
4 changes: 4 additions & 0 deletions src/application/ScenarioResultWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,10 @@ const safecrowd::domain::ScenarioResultArtifacts& ScenarioResultWidget::artifact
return artifacts_;
}

const std::optional<ScenarioAuthoringWidget::InitialState>& ScenarioResultWidget::returnAuthoringState() const noexcept {
return returnAuthoringState_;
}

void ScenarioResultWidget::rerunScenario() {
auto* rootLayout = qobject_cast<QVBoxLayout*>(layout());
if (rootLayout == nullptr || shell_ == nullptr) {
Expand Down
1 change: 1 addition & 0 deletions src/application/ScenarioResultWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ScenarioResultWidget : public QWidget {
const safecrowd::domain::SimulationFrame& frame() const noexcept;
const safecrowd::domain::ScenarioRiskSnapshot& risk() const noexcept;
const safecrowd::domain::ScenarioResultArtifacts& artifacts() const noexcept;
const std::optional<ScenarioAuthoringWidget::InitialState>& returnAuthoringState() const noexcept;

private:
enum class ResultNavigationView {
Expand Down
4 changes: 4 additions & 0 deletions src/application/ScenarioRunWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ const safecrowd::domain::ScenarioDraft& ScenarioRunWidget::scenario() const noex
return scenario_;
}

const std::optional<ScenarioAuthoringWidget::InitialState>& ScenarioRunWidget::returnAuthoringState() const noexcept {
return returnAuthoringState_;
}

QWidget* ScenarioRunWidget::createRunPanel() {
auto* panel = new QWidget(shell_);
auto* layout = new QVBoxLayout(panel);
Expand Down
1 change: 1 addition & 0 deletions src/application/ScenarioRunWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ScenarioRunWidget : public QWidget {
std::optional<ScenarioAuthoringWidget::InitialState> returnAuthoringState = std::nullopt);

const safecrowd::domain::ScenarioDraft& scenario() const noexcept;
const std::optional<ScenarioAuthoringWidget::InitialState>& returnAuthoringState() const noexcept;

private:
QWidget* createRunPanel();
Expand Down
Loading
Loading