Use std::optional instead of sentinel values for absent data
This commit is contained in:
@@ -28,7 +28,6 @@ BlueprintPanel::BlueprintPanel(Simulation* sim, const GameConfig* config, QWidge
|
||||
, m_sim(sim)
|
||||
, m_config(config)
|
||||
, m_currentBlocks(0)
|
||||
, m_activeIndex(-1)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(4, 4, 4, 4);
|
||||
@@ -80,11 +79,11 @@ void BlueprintPanel::handleEvent(std::shared_ptr<const BuildingBlocksChangedEven
|
||||
|
||||
void BlueprintPanel::clearActiveBlueprintButton()
|
||||
{
|
||||
if (m_activeIndex >= 0 && m_activeIndex < static_cast<int>(m_blueprintButtons.size()))
|
||||
if (m_activeIndex.has_value() && *m_activeIndex < static_cast<int>(m_blueprintButtons.size()))
|
||||
{
|
||||
m_blueprintButtons[static_cast<std::size_t>(m_activeIndex)]->setChecked(false);
|
||||
m_blueprintButtons[static_cast<std::size_t>(*m_activeIndex)]->setChecked(false);
|
||||
}
|
||||
m_activeIndex = -1;
|
||||
m_activeIndex = std::nullopt;
|
||||
refreshButtonStates();
|
||||
}
|
||||
|
||||
@@ -109,13 +108,13 @@ void BlueprintPanel::onDeleteBlueprintClicked(int index)
|
||||
{
|
||||
if (m_activeIndex == index)
|
||||
{
|
||||
m_activeIndex = -1;
|
||||
m_activeIndex = std::nullopt;
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<ExitBlueprintModeRequestedEvent>());
|
||||
}
|
||||
else if (m_activeIndex > index)
|
||||
else if (m_activeIndex.has_value() && *m_activeIndex > index)
|
||||
{
|
||||
m_activeIndex--;
|
||||
--*m_activeIndex;
|
||||
}
|
||||
m_blueprints.erase(m_blueprints.begin() + index);
|
||||
rebuildButtons();
|
||||
@@ -133,9 +132,9 @@ void BlueprintPanel::onBlueprintButtonClicked(int index)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_activeIndex >= 0 && m_activeIndex < static_cast<int>(m_blueprintButtons.size()))
|
||||
if (m_activeIndex.has_value() && *m_activeIndex < static_cast<int>(m_blueprintButtons.size()))
|
||||
{
|
||||
m_blueprintButtons[static_cast<std::size_t>(m_activeIndex)]->setChecked(false);
|
||||
m_blueprintButtons[static_cast<std::size_t>(*m_activeIndex)]->setChecked(false);
|
||||
}
|
||||
|
||||
m_activeIndex = index;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <QWidget>
|
||||
@@ -56,7 +57,7 @@ private:
|
||||
const GameConfig* m_config;
|
||||
std::vector<BuildingId> m_selectedBuildingIds;
|
||||
int m_currentBlocks;
|
||||
int m_activeIndex;
|
||||
std::optional<int> m_activeIndex; // nullopt = no blueprint selected
|
||||
std::vector<Blueprint> m_blueprints;
|
||||
std::vector<QPushButton*> m_blueprintButtons;
|
||||
QPushButton* m_createBtn;
|
||||
|
||||
@@ -142,7 +142,6 @@ GameWorldView::GameWorldView(Simulation* sim, const GameConfig* config,
|
||||
, m_ghostValid(false)
|
||||
, m_dragging(false)
|
||||
, m_demolishMode(false)
|
||||
, m_demolishHoverBuildingId(kInvalidBuildingId)
|
||||
, m_debugDraw(false)
|
||||
, m_rng(std::random_device{}())
|
||||
, m_boxSelecting(false)
|
||||
@@ -621,34 +620,34 @@ bool GameWorldView::isValidPlacement(BuildingType type, QPoint anchor,
|
||||
return true;
|
||||
}
|
||||
|
||||
BuildingId GameWorldView::buildingAtTile(QPoint tile) const
|
||||
std::optional<BuildingId> GameWorldView::buildingAtTile(QPoint tile) const
|
||||
{
|
||||
for (const Building& b : m_sim->getBuildings().getAllBuildings())
|
||||
{
|
||||
for (const QPoint& cell : b.bodyCells)
|
||||
{
|
||||
if (cell == tile)
|
||||
{
|
||||
return b.id;
|
||||
if (cell == tile)
|
||||
{
|
||||
return b.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return kInvalidBuildingId;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
BuildingId GameWorldView::siteAtTile(QPoint tile) const
|
||||
std::optional<BuildingId> GameWorldView::siteAtTile(QPoint tile) const
|
||||
{
|
||||
for (const ConstructionSite& s : m_sim->getBuildings().getAllSites())
|
||||
{
|
||||
for (const QPoint& cell : s.bodyCells)
|
||||
{
|
||||
if (cell == tile)
|
||||
if (cell == tile)
|
||||
{
|
||||
return s.id;
|
||||
return s.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return kInvalidBuildingId;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -1617,9 +1616,9 @@ void GameWorldView::drawOverlays(QPainter& painter)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_demolishMode && m_demolishHoverBuildingId != kInvalidBuildingId)
|
||||
else if (m_demolishMode && m_demolishHoverBuildingId.has_value())
|
||||
{
|
||||
const Building* b = m_sim->getBuildings().findBuilding(m_demolishHoverBuildingId);
|
||||
const Building* b = m_sim->getBuildings().findBuilding(*m_demolishHoverBuildingId);
|
||||
if (b)
|
||||
{
|
||||
for (const QPoint& cell : b->bodyCells)
|
||||
@@ -1989,9 +1988,9 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
// Shift + right-click copies a building's settings, but only in the
|
||||
// default selection mode (REQ-BLD-COPY-CONFIG).
|
||||
const QPoint tile = widgetToTile(event->pos());
|
||||
BuildingId id = buildingAtTile(tile);
|
||||
if (id == kInvalidBuildingId) { id = siteAtTile(tile); }
|
||||
if (id != kInvalidBuildingId) { copyConfigFrom(id); }
|
||||
std::optional<BuildingId> id = buildingAtTile(tile);
|
||||
if (!id.has_value()) { id = siteAtTile(tile); }
|
||||
if (id.has_value()) { copyConfigFrom(*id); }
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -2032,11 +2031,11 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
// selection. Only active in the default selection mode.
|
||||
if ((event->modifiers() & Qt::ShiftModifier) && m_copiedConfig.has_value())
|
||||
{
|
||||
BuildingId id = buildingAtTile(tile);
|
||||
if (id == kInvalidBuildingId) { id = siteAtTile(tile); }
|
||||
if (id != kInvalidBuildingId)
|
||||
std::optional<BuildingId> id = buildingAtTile(tile);
|
||||
if (!id.has_value()) { id = siteAtTile(tile); }
|
||||
if (id.has_value())
|
||||
{
|
||||
pasteConfigTo(id);
|
||||
pasteConfigTo(*id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2064,13 +2063,14 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
std::make_shared<EntitySelectedEvent>(std::nullopt));
|
||||
}
|
||||
|
||||
BuildingId id = buildingAtTile(tile);
|
||||
if (id == kInvalidBuildingId)
|
||||
std::optional<BuildingId> hit = buildingAtTile(tile);
|
||||
if (!hit.has_value())
|
||||
{
|
||||
id = siteAtTile(tile);
|
||||
hit = siteAtTile(tile);
|
||||
}
|
||||
if (id != kInvalidBuildingId)
|
||||
if (hit.has_value())
|
||||
{
|
||||
const BuildingId id = *hit;
|
||||
// A building/construction site outranks scrap (REQ-UI-SCRAP-CLICK-SELECT).
|
||||
clearScrapSelection();
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
@@ -2198,7 +2198,7 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
command->id = id;
|
||||
enqueueCommand(command);
|
||||
}
|
||||
m_demolishHoverBuildingId = kInvalidBuildingId;
|
||||
m_demolishHoverBuildingId = std::nullopt;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2283,7 +2283,7 @@ void GameWorldView::toggleDemolishMode()
|
||||
if (m_demolishMode)
|
||||
{
|
||||
m_demolishMode = false;
|
||||
m_demolishHoverBuildingId = kInvalidBuildingId;
|
||||
m_demolishHoverBuildingId = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2479,7 +2479,7 @@ void GameWorldView::resetForNewGame()
|
||||
m_ghostRotation = Rotation::East;
|
||||
m_ghostValid = false;
|
||||
m_demolishMode = false;
|
||||
m_demolishHoverBuildingId = kInvalidBuildingId;
|
||||
m_demolishHoverBuildingId = std::nullopt;
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<DemolishModeChangedEvent>(false));
|
||||
m_selectedBuildingIds.clear();
|
||||
|
||||
@@ -168,8 +168,8 @@ private:
|
||||
|
||||
bool isValidPlacement(BuildingType type, QPoint anchor, Rotation rot) const;
|
||||
const BuildingDef* findBuildingDef(BuildingType type) const;
|
||||
BuildingId buildingAtTile(QPoint tile) const;
|
||||
BuildingId siteAtTile(QPoint tile) const;
|
||||
std::optional<BuildingId> buildingAtTile(QPoint tile) const;
|
||||
std::optional<BuildingId> siteAtTile(QPoint tile) const;
|
||||
// Ids of all buildings and construction sites whose footprint intersects
|
||||
// the tile box spanned by the two (unordered) corner tiles.
|
||||
std::vector<BuildingId> buildingsInBox(QPoint cornerA, QPoint cornerB) const;
|
||||
@@ -270,7 +270,7 @@ private:
|
||||
static constexpr qint64 kCopyFlashDurationMs = 300;
|
||||
|
||||
bool m_demolishMode;
|
||||
BuildingId m_demolishHoverBuildingId;
|
||||
std::optional<BuildingId> m_demolishHoverBuildingId;
|
||||
bool m_debugDraw;
|
||||
|
||||
std::vector<BuildingId> m_selectedBuildingIds;
|
||||
|
||||
@@ -131,7 +131,6 @@ SelectedBuildingPanel::SelectedBuildingPanel(Simulation* sim,
|
||||
: QWidget(parent)
|
||||
, m_sim(sim)
|
||||
, m_config(config)
|
||||
, m_singleBuildingId(kInvalidBuildingId)
|
||||
, m_splitterTile(0, 0)
|
||||
{
|
||||
m_layout = new QVBoxLayout(this);
|
||||
@@ -170,10 +169,10 @@ SelectedBuildingPanel::SelectedBuildingPanel(Simulation* sim,
|
||||
connect(m_clearBeltBtn, &QPushButton::clicked,
|
||||
this, &SelectedBuildingPanel::onClearBelt);
|
||||
connect(m_configureLayoutBtn, &QPushButton::clicked, this, [this]() {
|
||||
if (m_singleBuildingId != kInvalidBuildingId)
|
||||
if (m_singleBuildingId.has_value())
|
||||
{
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<LayoutDialogRequestedEvent>(m_singleBuildingId));
|
||||
std::make_shared<LayoutDialogRequestedEvent>(*m_singleBuildingId));
|
||||
}
|
||||
});
|
||||
connect(m_filterAList, &QListWidget::itemChanged,
|
||||
@@ -257,7 +256,7 @@ void SelectedBuildingPanel::hideAllWidgets()
|
||||
|
||||
void SelectedBuildingPanel::clearContent()
|
||||
{
|
||||
m_singleBuildingId = kInvalidBuildingId;
|
||||
m_singleBuildingId = std::nullopt;
|
||||
hideAllWidgets();
|
||||
}
|
||||
|
||||
@@ -672,8 +671,8 @@ void SelectedBuildingPanel::refreshSelectionDisplay(RefreshReason reason)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_singleBuildingId == kInvalidBuildingId) { return; }
|
||||
const Building* b = m_sim->getBuildings().findBuilding(m_singleBuildingId);
|
||||
if (!m_singleBuildingId.has_value()) { return; }
|
||||
const Building* b = m_sim->getBuildings().findBuilding(*m_singleBuildingId);
|
||||
if (b)
|
||||
{
|
||||
if (m_titleLabel->text().startsWith(tr("(Building) ")))
|
||||
@@ -686,7 +685,7 @@ void SelectedBuildingPanel::refreshSelectionDisplay(RefreshReason reason)
|
||||
}
|
||||
return;
|
||||
}
|
||||
const ConstructionSite* s = m_sim->getBuildings().findSite(m_singleBuildingId);
|
||||
const ConstructionSite* s = m_sim->getBuildings().findSite(*m_singleBuildingId);
|
||||
if (s)
|
||||
{
|
||||
// A periodic tick only advances construction progress, so update just the
|
||||
@@ -708,7 +707,7 @@ void SelectedBuildingPanel::refreshSelectionDisplay(RefreshReason reason)
|
||||
|
||||
void SelectedBuildingPanel::buildMulti(const std::vector<BuildingId>& ids)
|
||||
{
|
||||
m_singleBuildingId = kInvalidBuildingId;
|
||||
m_singleBuildingId = std::nullopt;
|
||||
m_recipeSelectButton->hide();
|
||||
m_clearBeltBtn->hide();
|
||||
m_filterALabel->hide();
|
||||
@@ -764,7 +763,7 @@ void SelectedBuildingPanel::buildMulti(const std::vector<BuildingId>& ids)
|
||||
|
||||
void SelectedBuildingPanel::onSelectRecipeClicked()
|
||||
{
|
||||
if (m_singleBuildingId == kInvalidBuildingId)
|
||||
if (!m_singleBuildingId.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -775,7 +774,7 @@ void SelectedBuildingPanel::onSelectRecipeClicked()
|
||||
// refreshBuffers() path picks up the new schematic (and shows the layout
|
||||
// preview + Configure Layout button) once the command has been applied.
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<RecipeSelectionRequestedEvent>(m_singleBuildingId));
|
||||
std::make_shared<RecipeSelectionRequestedEvent>(*m_singleBuildingId));
|
||||
rebuild();
|
||||
}
|
||||
|
||||
@@ -825,7 +824,7 @@ void SelectedBuildingPanel::buildSplitterFilters(
|
||||
|
||||
void SelectedBuildingPanel::onSplitterFilterChanged()
|
||||
{
|
||||
if (m_singleBuildingId == kInvalidBuildingId)
|
||||
if (!m_singleBuildingId.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -848,7 +847,7 @@ void SelectedBuildingPanel::onSplitterFilterChanged()
|
||||
{
|
||||
std::shared_ptr<SetSiteSplitterFiltersCommand> command =
|
||||
std::make_shared<SetSiteSplitterFiltersCommand>();
|
||||
command->id = m_singleBuildingId;
|
||||
command->id = *m_singleBuildingId;
|
||||
command->filterA = collectFilter(m_filterAList);
|
||||
command->filterB = collectFilter(m_filterBList);
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
|
||||
@@ -109,7 +109,7 @@ private:
|
||||
ShipLayoutPreview* m_layoutPreview;
|
||||
QPushButton* m_configureLayoutBtn;
|
||||
|
||||
BuildingId m_singleBuildingId;
|
||||
std::optional<BuildingId> m_singleBuildingId;
|
||||
bool m_singleIsSite = false; // selected single entity is a construction site
|
||||
QPoint m_splitterTile;
|
||||
std::string m_currentRecipeId;
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
setFixedSize(cols * kCellSize + 1, rows * kCellSize + 1);
|
||||
}
|
||||
|
||||
void setGhostData(int moduleIndex, Rotation rotation)
|
||||
void setGhostData(std::optional<int> moduleIndex, Rotation rotation)
|
||||
{
|
||||
m_ghostModuleIdx = moduleIndex;
|
||||
m_ghostRotation = rotation;
|
||||
@@ -111,9 +111,9 @@ protected:
|
||||
{
|
||||
painter.fillRect(cellRect, QColor(30, 30, 30));
|
||||
}
|
||||
else if (cell.moduleIndex >= 0)
|
||||
else if (cell.moduleIndex.has_value())
|
||||
{
|
||||
const PlacedModule& pm = (*m_placed)[cell.moduleIndex];
|
||||
const PlacedModule& pm = (*m_placed)[*cell.moduleIndex];
|
||||
const ModuleDef* def = findModule(pm.moduleId);
|
||||
QColor color(Qt::gray);
|
||||
QString glyph;
|
||||
@@ -140,9 +140,9 @@ protected:
|
||||
}
|
||||
|
||||
// Draw ghost
|
||||
if (m_ghostModuleIdx >= 0 && m_hoverCell.x() >= 0 && m_config)
|
||||
if (m_ghostModuleIdx.has_value() && m_hoverCell.x() >= 0 && m_config)
|
||||
{
|
||||
const ModuleDef& def = m_config->modules.modules[m_ghostModuleIdx];
|
||||
const ModuleDef& def = m_config->modules.modules[*m_ghostModuleIdx];
|
||||
const std::vector<std::string> mask = rotateMask(def.surfaceMask, m_ghostRotation);
|
||||
QColor ghostColor(QString::fromStdString(def.fillColor));
|
||||
ghostColor.setAlpha(100);
|
||||
@@ -238,7 +238,7 @@ private:
|
||||
int m_cols = 0;
|
||||
const std::vector<PlacedModule>* m_placed = nullptr;
|
||||
const GameConfig* m_config = nullptr;
|
||||
int m_ghostModuleIdx = -2;
|
||||
std::optional<int> m_ghostModuleIdx;
|
||||
Rotation m_ghostRotation = Rotation::East;
|
||||
QPoint m_hoverCell = QPoint(-1, -1);
|
||||
};
|
||||
@@ -374,7 +374,6 @@ ShipLayoutDialog::ShipLayoutDialog(const GameConfig* config,
|
||||
, m_rows(0)
|
||||
, m_cols(0)
|
||||
, m_placedModules(currentLayout.placedModules)
|
||||
, m_activeModuleIndex(-2)
|
||||
, m_currentRotation(Rotation::East)
|
||||
, m_removeButton(nullptr)
|
||||
, m_gridWidget(nullptr)
|
||||
@@ -406,7 +405,7 @@ ShipLayoutDialog::ShipLayoutDialog(const GameConfig* config,
|
||||
}
|
||||
|
||||
// Initialize grid.
|
||||
m_grid.assign(m_rows, std::vector<CellInfo>(m_cols, {false, -1}));
|
||||
m_grid.assign(m_rows, std::vector<CellInfo>(m_cols, {false, std::nullopt}));
|
||||
for (int r = 0; r < m_rows; ++r)
|
||||
{
|
||||
for (int c = 0; c < static_cast<int>(m_shipLayout[r].size()); ++c)
|
||||
@@ -491,9 +490,9 @@ ShipLayoutDialog::ShipLayoutDialog(const GameConfig* config,
|
||||
}
|
||||
buttonGrid->addWidget(m_removeButton, row, 0, 1, kCols);
|
||||
connect(m_removeButton, &QPushButton::clicked, this, [this]() {
|
||||
if (m_activeModuleIndex == -1)
|
||||
if (m_removeMode)
|
||||
{
|
||||
m_activeModuleIndex = -2;
|
||||
m_removeMode = false;
|
||||
m_removeButton->setChecked(false);
|
||||
}
|
||||
else
|
||||
@@ -502,7 +501,8 @@ ShipLayoutDialog::ShipLayoutDialog(const GameConfig* config,
|
||||
{
|
||||
if (btn) { btn->setChecked(false); }
|
||||
}
|
||||
m_activeModuleIndex = -1;
|
||||
m_activeModuleIndex = std::nullopt;
|
||||
m_removeMode = true;
|
||||
m_removeButton->setChecked(true);
|
||||
}
|
||||
updateGridWidget();
|
||||
@@ -540,20 +540,20 @@ ShipLayoutDialog::ShipLayoutDialog(const GameConfig* config,
|
||||
|
||||
// Grid click handler.
|
||||
connect(this, &ShipLayoutDialog::gridCellClicked, this, [this](QPoint cell) {
|
||||
if (m_activeModuleIndex == -2)
|
||||
if (!m_removeMode && !m_activeModuleIndex.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_activeModuleIndex == -1)
|
||||
if (m_removeMode)
|
||||
{
|
||||
// Remove mode: find and remove module at cell.
|
||||
if (cell.y() >= 0 && cell.y() < m_rows && cell.x() >= 0 && cell.x() < m_cols)
|
||||
{
|
||||
const int idx = m_grid[cell.y()][cell.x()].moduleIndex;
|
||||
if (idx >= 0)
|
||||
const std::optional<int> idx = m_grid[cell.y()][cell.x()].moduleIndex;
|
||||
if (idx.has_value())
|
||||
{
|
||||
m_placedModules.erase(m_placedModules.begin() + idx);
|
||||
m_placedModules.erase(m_placedModules.begin() + *idx);
|
||||
rebuildOccupancy();
|
||||
updateGridWidget();
|
||||
updateStats();
|
||||
@@ -563,7 +563,7 @@ ShipLayoutDialog::ShipLayoutDialog(const GameConfig* config,
|
||||
}
|
||||
|
||||
// Place module.
|
||||
const ModuleDef& def = m_config->modules.modules[m_activeModuleIndex];
|
||||
const ModuleDef& def = m_config->modules.modules[*m_activeModuleIndex];
|
||||
if (canPlaceModule(def, cell, m_currentRotation))
|
||||
{
|
||||
PlacedModule pm;
|
||||
@@ -622,7 +622,7 @@ void ShipLayoutDialog::onModuleButtonClicked(int index)
|
||||
if (m_activeModuleIndex == index)
|
||||
{
|
||||
if (m_moduleButtons[index]) { m_moduleButtons[index]->setChecked(false); }
|
||||
m_activeModuleIndex = -2;
|
||||
m_activeModuleIndex = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -631,6 +631,7 @@ void ShipLayoutDialog::onModuleButtonClicked(int index)
|
||||
if (m_moduleButtons[i]) { m_moduleButtons[i]->setChecked(i == index); }
|
||||
}
|
||||
m_removeButton->setChecked(false);
|
||||
m_removeMode = false;
|
||||
m_activeModuleIndex = index;
|
||||
}
|
||||
updateGridWidget();
|
||||
@@ -656,7 +657,7 @@ void ShipLayoutDialog::rebuildOccupancy()
|
||||
{
|
||||
for (int c = 0; c < m_cols; ++c)
|
||||
{
|
||||
m_grid[r][c].moduleIndex = -1;
|
||||
m_grid[r][c].moduleIndex = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,7 +727,7 @@ bool ShipLayoutDialog::canPlaceModule(const ModuleDef& def, QPoint position,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (m_grid[gr][gc].moduleIndex >= 0)
|
||||
if (m_grid[gr][gc].moduleIndex.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
struct CellInfo
|
||||
{
|
||||
bool buildable;
|
||||
int moduleIndex; // -1 if empty
|
||||
std::optional<int> moduleIndex; // nullopt if empty
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -69,7 +69,12 @@ private:
|
||||
std::vector<PlacedModule> m_placedModules;
|
||||
std::vector<std::vector<CellInfo>> m_grid;
|
||||
|
||||
int m_activeModuleIndex; // -1 = remove mode, -2 = no selection
|
||||
// The module to place, as an index into config modules; nullopt when no
|
||||
// module is selected for placement. m_removeMode is a separate mode in which
|
||||
// clicking a cell removes the module there (mutually exclusive with a
|
||||
// selected module).
|
||||
std::optional<int> m_activeModuleIndex;
|
||||
bool m_removeMode = false;
|
||||
Rotation m_currentRotation;
|
||||
|
||||
std::vector<QPushButton*> m_moduleButtons;
|
||||
|
||||
@@ -129,7 +129,7 @@ void ShipLayoutPreview::setShipAndLayout(const std::vector<std::string>& shipLay
|
||||
}
|
||||
}
|
||||
|
||||
m_grid.assign(m_rows, std::vector<CellInfo>(m_cols, {false, -1}));
|
||||
m_grid.assign(m_rows, std::vector<CellInfo>(m_cols, {false, std::nullopt}));
|
||||
for (int r = 0; r < m_rows; ++r)
|
||||
{
|
||||
for (int c = 0; c < static_cast<int>(shipLayout[r].size()); ++c)
|
||||
@@ -205,9 +205,9 @@ void ShipLayoutPreview::paintEvent(QPaintEvent* /*event*/)
|
||||
{
|
||||
painter.fillRect(cellRect, Qt::black);
|
||||
}
|
||||
else if (cell.moduleIndex >= 0)
|
||||
else if (cell.moduleIndex.has_value())
|
||||
{
|
||||
const PlacedModule& pm = m_placedModules[cell.moduleIndex];
|
||||
const PlacedModule& pm = m_placedModules[*cell.moduleIndex];
|
||||
const ModuleDef* def = findModuleDef(*m_modules, pm.moduleId);
|
||||
QColor color(Qt::gray);
|
||||
if (def)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -31,7 +32,7 @@ private:
|
||||
struct CellInfo
|
||||
{
|
||||
bool buildable;
|
||||
int moduleIndex; // -1 if empty
|
||||
std::optional<int> moduleIndex; // nullopt if empty
|
||||
};
|
||||
|
||||
std::vector<std::vector<CellInfo>> m_grid;
|
||||
|
||||
Reference in New Issue
Block a user