From 4e3e3ac71549fc2ea136a34889c26ca5518b6ab6 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Fri, 5 Jun 2026 18:10:40 +0200 Subject: [PATCH] replace combined stateUpdated signal with individual events --- src/lib/eventsystem/EventManager.cpp | 6 +++ src/lib/eventsystem/EventManager.h | 1 + .../eventsystem/event/BossWaveUpdatedEvent.h | 17 ++++++ .../event/BuildingBlocksChangedEvent.h | 14 +++++ src/lib/eventsystem/event/CMakeLists.txt | 4 ++ .../eventsystem/event/GameSpeedChangedEvent.h | 14 +++++ src/lib/eventsystem/event/TickAdvancedEvent.h | 15 ++++++ src/lib/sim/Simulation.cpp | 2 +- src/ui/BlueprintPanel.cpp | 12 ++++- src/ui/BlueprintPanel.h | 10 +++- src/ui/GameWorldView.cpp | 50 ++++++++++++----- src/ui/GameWorldView.h | 6 ++- src/ui/HeaderBar.cpp | 53 +++++++++++-------- src/ui/HeaderBar.h | 21 ++++++-- src/ui/MainWindow.cpp | 24 ++++----- src/ui/MainWindow.h | 13 +++-- src/ui/SelectedBuildingPanel.cpp | 10 +++- src/ui/SelectedBuildingPanel.h | 10 +++- 18 files changed, 216 insertions(+), 66 deletions(-) create mode 100644 src/lib/eventsystem/event/BossWaveUpdatedEvent.h create mode 100644 src/lib/eventsystem/event/BuildingBlocksChangedEvent.h create mode 100644 src/lib/eventsystem/event/GameSpeedChangedEvent.h create mode 100644 src/lib/eventsystem/event/TickAdvancedEvent.h diff --git a/src/lib/eventsystem/EventManager.cpp b/src/lib/eventsystem/EventManager.cpp index 9c27070..2e7789f 100644 --- a/src/lib/eventsystem/EventManager.cpp +++ b/src/lib/eventsystem/EventManager.cpp @@ -117,6 +117,12 @@ void EventManager::processEvents() } } +void EventManager::clearEvents() +{ + std::scoped_lock lock(m_eventsMutex); + m_events.clear(); +} + bool EventManager::hasEvents() const { return !m_events.empty(); diff --git a/src/lib/eventsystem/EventManager.h b/src/lib/eventsystem/EventManager.h index 2654afb..88e6952 100644 --- a/src/lib/eventsystem/EventManager.h +++ b/src/lib/eventsystem/EventManager.h @@ -28,6 +28,7 @@ public: void sendEventImmediately(std::shared_ptr event); void addEvent(std::shared_ptr event); void processEvents(); + void clearEvents(); bool hasEvents() const; diff --git a/src/lib/eventsystem/event/BossWaveUpdatedEvent.h b/src/lib/eventsystem/event/BossWaveUpdatedEvent.h new file mode 100644 index 0000000..5fbf24d --- /dev/null +++ b/src/lib/eventsystem/event/BossWaveUpdatedEvent.h @@ -0,0 +1,17 @@ +#ifndef BOSS_WAVE_UPDATED_EVENT_H +#define BOSS_WAVE_UPDATED_EVENT_H + +#include "Event.h" +#include "Tick.h" + +class BossWaveUpdatedEvent : public Event +{ +public: + BossWaveUpdatedEvent(int counter, Tick countdownTicks) + : counter(counter), countdownTicks(countdownTicks) {} + const int counter; + const Tick countdownTicks; +}; + +#endif // BOSS_WAVE_UPDATED_EVENT_H + diff --git a/src/lib/eventsystem/event/BuildingBlocksChangedEvent.h b/src/lib/eventsystem/event/BuildingBlocksChangedEvent.h new file mode 100644 index 0000000..2b02b8a --- /dev/null +++ b/src/lib/eventsystem/event/BuildingBlocksChangedEvent.h @@ -0,0 +1,14 @@ +#ifndef BUILDING_BLOCKS_CHANGED_EVENT_H +#define BUILDING_BLOCKS_CHANGED_EVENT_H + +#include "Event.h" + +class BuildingBlocksChangedEvent : public Event +{ +public: + explicit BuildingBlocksChangedEvent(int blocks) : blocks(blocks) {} + const int blocks; +}; + +#endif // BUILDING_BLOCKS_CHANGED_EVENT_H + diff --git a/src/lib/eventsystem/event/CMakeLists.txt b/src/lib/eventsystem/event/CMakeLists.txt index 3ec8c7a..d0323f0 100644 --- a/src/lib/eventsystem/event/CMakeLists.txt +++ b/src/lib/eventsystem/event/CMakeLists.txt @@ -1,6 +1,10 @@ SET(HDRS ${HDRS} ${CMAKE_CURRENT_SOURCE_DIR}/TracePrintRequestedEvent.h + ${CMAKE_CURRENT_SOURCE_DIR}/TickAdvancedEvent.h + ${CMAKE_CURRENT_SOURCE_DIR}/BuildingBlocksChangedEvent.h + ${CMAKE_CURRENT_SOURCE_DIR}/GameSpeedChangedEvent.h + ${CMAKE_CURRENT_SOURCE_DIR}/BossWaveUpdatedEvent.h PARENT_SCOPE ) diff --git a/src/lib/eventsystem/event/GameSpeedChangedEvent.h b/src/lib/eventsystem/event/GameSpeedChangedEvent.h new file mode 100644 index 0000000..225e981 --- /dev/null +++ b/src/lib/eventsystem/event/GameSpeedChangedEvent.h @@ -0,0 +1,14 @@ +#ifndef GAME_SPEED_CHANGED_EVENT_H +#define GAME_SPEED_CHANGED_EVENT_H + +#include "Event.h" + +class GameSpeedChangedEvent : public Event +{ +public: + explicit GameSpeedChangedEvent(double speed) : speed(speed) {} + const double speed; +}; + +#endif // GAME_SPEED_CHANGED_EVENT_H + diff --git a/src/lib/eventsystem/event/TickAdvancedEvent.h b/src/lib/eventsystem/event/TickAdvancedEvent.h new file mode 100644 index 0000000..3f95ccb --- /dev/null +++ b/src/lib/eventsystem/event/TickAdvancedEvent.h @@ -0,0 +1,15 @@ +#ifndef TICK_ADVANCED_EVENT_H +#define TICK_ADVANCED_EVENT_H + +#include "Event.h" +#include "Tick.h" + +class TickAdvancedEvent : public Event +{ +public: + explicit TickAdvancedEvent(Tick tick) : tick(tick) {} + const Tick tick; +}; + +#endif // TICK_ADVANCED_EVENT_H + diff --git a/src/lib/sim/Simulation.cpp b/src/lib/sim/Simulation.cpp index ff75f28..8de047b 100644 --- a/src/lib/sim/Simulation.cpp +++ b/src/lib/sim/Simulation.cpp @@ -93,7 +93,7 @@ void Simulation::reset(GameConfig newConfig, unsigned int seed) void Simulation::reset(unsigned int seed) { - EventManager::destroyInstance(); + EventManager::getInstance()->clearEvents(); m_rng.seed(seed); m_currentTick = 0; m_nextDepartureTick = secondsToTicks(m_config.world.departureIntervalSeconds); diff --git a/src/ui/BlueprintPanel.cpp b/src/ui/BlueprintPanel.cpp index 763b407..bc6d431 100644 --- a/src/ui/BlueprintPanel.cpp +++ b/src/ui/BlueprintPanel.cpp @@ -13,6 +13,7 @@ #include #include "BlueprintSerializer.h" +#include "BuildingBlocksChangedEvent.h" #include "Building.h" #include "BuildingSystem.h" @@ -60,6 +61,13 @@ BlueprintPanel::BlueprintPanel(Simulation* sim, const GameConfig* config, QWidge connect(m_saveBtn, &QPushButton::clicked, this, &BlueprintPanel::onSaveClicked); connect(m_loadBtn, &QPushButton::clicked, this, &BlueprintPanel::onLoadClicked); + + registerForEvent(); +} + +BlueprintPanel::~BlueprintPanel() +{ + unregisterForEvent(); } void BlueprintPanel::onSelectionChanged(const std::vector& ids) @@ -68,9 +76,9 @@ void BlueprintPanel::onSelectionChanged(const std::vector& ids) refreshButtonStates(); } -void BlueprintPanel::onStateUpdated(Tick /*tick*/, int blocks, double /*speed*/) +void BlueprintPanel::handleEvent(std::shared_ptr event) { - m_currentBlocks = blocks; + m_currentBlocks = event->blocks; refreshButtonStates(); } diff --git a/src/ui/BlueprintPanel.h b/src/ui/BlueprintPanel.h index cbf557e..563e0a3 100644 --- a/src/ui/BlueprintPanel.h +++ b/src/ui/BlueprintPanel.h @@ -5,7 +5,9 @@ #include #include "Blueprint.h" +#include "BuildingBlocksChangedEvent.h" #include "BuildingId.h" +#include "EventHandler.h" #include "GameConfig.h" #include "Tick.h" @@ -14,22 +16,26 @@ class QPushButton; class QScrollArea; class QVBoxLayout; -class BlueprintPanel : public QWidget +class BlueprintPanel : public QWidget, + public EventHandler { Q_OBJECT public: BlueprintPanel(Simulation* sim, const GameConfig* config, QWidget* parent = nullptr); + ~BlueprintPanel() override; public slots: void onSelectionChanged(const std::vector& ids); - void onStateUpdated(Tick tick, int blocks, double speed); void clearActiveBlueprintButton(); signals: void blueprintPlacementRequested(Blueprint blueprint); void exitBlueprintModeRequested(); +private: + void handleEvent(std::shared_ptr event) override; + private slots: void onCreateClicked(); void onDeleteBlueprintClicked(int index); diff --git a/src/ui/GameWorldView.cpp b/src/ui/GameWorldView.cpp index 2781ff0..2ae218b 100644 --- a/src/ui/GameWorldView.cpp +++ b/src/ui/GameWorldView.cpp @@ -34,6 +34,10 @@ #include "SurfaceMask.h" #include "Tick.h" #include "TracePrintRequestedEvent.h" +#include "BossWaveUpdatedEvent.h" +#include "BuildingBlocksChangedEvent.h" +#include "GameSpeedChangedEvent.h" +#include "TickAdvancedEvent.h" namespace { @@ -239,12 +243,33 @@ void GameWorldView::onFrame() clampScroll(); } - // Emit state update for header bar / build grid - emit stateUpdated(m_sim->currentTick(), - m_sim->buildingBlocksStock(), - m_gameSpeedMultiplier, - m_sim->bossWaveCounter(), - m_sim->bossCountdownTicks()); + // Fire events for any state that changed since the last frame + { + const Tick newTick = m_sim->currentTick(); + const int newBlocks = m_sim->buildingBlocksStock(); + const int newBoss = m_sim->bossWaveCounter(); + const Tick newCountdown = m_sim->bossCountdownTicks(); + + if (newTick != m_lastTick) + { + m_lastTick = newTick; + EventManager::getInstance()->sendEventImmediately( + std::make_shared(newTick)); + } + if (newBlocks != m_lastBlocks) + { + m_lastBlocks = newBlocks; + EventManager::getInstance()->sendEventImmediately( + std::make_shared(newBlocks)); + } + if (newBoss != m_lastBossCounter || newCountdown != m_lastBossCountdown) + { + m_lastBossCounter = newBoss; + m_lastBossCountdown = newCountdown; + EventManager::getInstance()->sendEventImmediately( + std::make_shared(newBoss, newCountdown)); + } + } // Game over check if (m_sim->isGameOver() && !m_gameOverShown) @@ -1403,11 +1428,8 @@ double GameWorldView::gameSpeed() const void GameWorldView::setGameSpeed(double multiplier) { m_gameSpeedMultiplier = multiplier; - emit stateUpdated(m_sim->currentTick(), - m_sim->buildingBlocksStock(), - m_gameSpeedMultiplier, - m_sim->bossWaveCounter(), - m_sim->bossCountdownTicks()); + EventManager::getInstance()->sendEventImmediately( + std::make_shared(m_gameSpeedMultiplier)); } void GameWorldView::resetForNewGame() @@ -1427,8 +1449,12 @@ void GameWorldView::resetForNewGame() m_scrollLeft = false; m_scrollRight = false; m_gameOverShown = false; - m_gameSpeedMultiplier = 1.0; m_prevNonZeroSpeed = 1.0; + m_lastTick = Tick(-1); + m_lastBlocks = -1; + m_lastBossCounter = -1; + m_lastBossCountdown = Tick(-1); emit selectionChanged({}); + setGameSpeed(1.0); update(); } diff --git a/src/ui/GameWorldView.h b/src/ui/GameWorldView.h index a76501c..593bd7c 100644 --- a/src/ui/GameWorldView.h +++ b/src/ui/GameWorldView.h @@ -47,7 +47,6 @@ public: signals: void selectionChanged(const std::vector& ids); - void stateUpdated(Tick tick, int blocks, double speed, int bossCounter, Tick bossCountdownTicks); void gameOver(); void builderModeExited(); void blueprintModeExited(); @@ -173,4 +172,9 @@ private: bool m_scrollLeft; bool m_scrollRight; bool m_gameOverShown; + + Tick m_lastTick = Tick(-1); + int m_lastBlocks = -1; + int m_lastBossCounter = -1; + Tick m_lastBossCountdown = Tick(-1); }; diff --git a/src/ui/HeaderBar.cpp b/src/ui/HeaderBar.cpp index 68e96ad..ed342a9 100644 --- a/src/ui/HeaderBar.cpp +++ b/src/ui/HeaderBar.cpp @@ -41,41 +41,51 @@ HeaderBar::HeaderBar(QWidget* parent) connect(btn, &QPushButton::clicked, mapper, qOverload<>(&QSignalMapper::map)); } connect(mapper, qOverload(&QSignalMapper::mapped), this, &HeaderBar::onSpeedButton); - + setFixedHeight(sizeHint().height()); + + registerForEvents(); } -void HeaderBar::onStateUpdated(Tick tick, int buildingBlocks, double gameSpeed, - int bossCounter, Tick bossCountdownTicks) +HeaderBar::~HeaderBar() { - const int totalSeconds = static_cast(ticksToSeconds(tick)); - const int minutes = totalSeconds / 60; - const int seconds = totalSeconds % 60; + unregisterForEvents(); +} +void HeaderBar::handleEvent(std::shared_ptr event) +{ + const int totalSeconds = static_cast(ticksToSeconds(event->tick)); m_timeLabel->setText( QString("%1:%2") - .arg(minutes, 2, 10, QChar('0')) - .arg(seconds, 2, 10, QChar('0'))); + .arg(totalSeconds / 60, 2, 10, QChar('0')) + .arg(totalSeconds % 60, 2, 10, QChar('0'))); +} - m_blocksLabel->setText(tr("Blocks: %1").arg(buildingBlocks)); - - const int bossSeconds = static_cast(ticksToSeconds( - bossCountdownTicks > 0 ? bossCountdownTicks : 0)); - const int bossMin = bossSeconds / 60; - const int bossSec = bossSeconds % 60; - m_bossLabel->setText( - tr("Boss Wave #%1 Next boss: %2:%3") - .arg(bossCounter) - .arg(bossMin) - .arg(bossSec, 2, 10, QChar('0'))); +void HeaderBar::handleEvent(std::shared_ptr event) +{ + m_blocksLabel->setText(tr("Blocks: %1").arg(event->blocks)); +} +void HeaderBar::handleEvent(std::shared_ptr event) +{ for (int i = 0; i < kSpeedCount; ++i) { - const bool active = (std::abs(kSpeeds[i] - gameSpeed) < 0.001); - m_speedButtons[static_cast(i)]->setChecked(active); + m_speedButtons[static_cast(i)]->setChecked( + std::abs(kSpeeds[i] - event->speed) < 0.001); } } +void HeaderBar::handleEvent(std::shared_ptr event) +{ + const int bossSeconds = static_cast( + ticksToSeconds(event->countdownTicks > 0 ? event->countdownTicks : 0)); + m_bossLabel->setText( + tr("Boss Wave #%1 Next boss: %2:%3") + .arg(event->counter) + .arg(bossSeconds / 60) + .arg(bossSeconds % 60, 2, 10, QChar('0'))); +} + void HeaderBar::onSpeedButton(int index) { if (index >= 0 && index < kSpeedCount) @@ -83,4 +93,3 @@ void HeaderBar::onSpeedButton(int index) emit speedChanged(kSpeeds[index]); } } - diff --git a/src/ui/HeaderBar.h b/src/ui/HeaderBar.h index 0a991c4..6bcb1fe 100644 --- a/src/ui/HeaderBar.h +++ b/src/ui/HeaderBar.h @@ -4,21 +4,27 @@ #include +#include "BossWaveUpdatedEvent.h" +#include "BuildingBlocksChangedEvent.h" +#include "EventHandler.h" +#include "GameSpeedChangedEvent.h" #include "Tick.h" +#include "TickAdvancedEvent.h" class QLabel; class QPushButton; -class HeaderBar : public QWidget +class HeaderBar : public QWidget, + public CombinedEventHandler { Q_OBJECT public: explicit HeaderBar(QWidget* parent = nullptr); - -public slots: - void onStateUpdated(Tick tick, int buildingBlocks, double gameSpeed, - int bossCounter, Tick bossCountdownTicks); + ~HeaderBar() override; signals: void speedChanged(double multiplier); @@ -27,6 +33,11 @@ private slots: void onSpeedButton(int index); private: + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + QLabel* m_timeLabel; QLabel* m_blocksLabel; QLabel* m_bossLabel; diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index 4fbbf5f..6db9a05 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -11,6 +11,7 @@ #include "BlueprintPanel.h" #include "BuildButtonGrid.h" +#include "BuildingBlocksChangedEvent.h" #include "BuildingSystem.h" #include "ConfigLoader.h" #include "GameWorldView.h" @@ -52,15 +53,6 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir, QWidget* p connect(m_gameWorldView, &GameWorldView::selectionChanged, m_selectedBuildingPanel, &SelectedBuildingPanel::onSelectionChanged); - connect(m_gameWorldView, &GameWorldView::stateUpdated, - m_headerBar, &HeaderBar::onStateUpdated); - - connect(m_gameWorldView, &GameWorldView::stateUpdated, - this, &MainWindow::onStateUpdated); // for affordability - - connect(m_gameWorldView, &GameWorldView::stateUpdated, - m_selectedBuildingPanel, &SelectedBuildingPanel::onStateUpdated); - connect(m_gameWorldView, &GameWorldView::gameOver, this, &MainWindow::onGameOver); @@ -90,9 +82,6 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir, QWidget* p connect(m_gameWorldView, &GameWorldView::selectionChanged, m_blueprintPanel, &BlueprintPanel::onSelectionChanged); - connect(m_gameWorldView, &GameWorldView::stateUpdated, - m_blueprintPanel, &BlueprintPanel::onStateUpdated); - connect(m_blueprintPanel, &BlueprintPanel::blueprintPlacementRequested, m_gameWorldView, &GameWorldView::enterBlueprintMode); @@ -132,6 +121,13 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir, QWidget* p m_layoutBlueprints.clear(); } } + + registerForEvent(); +} + +MainWindow::~MainWindow() +{ + unregisterForEvent(); } void MainWindow::resizeEvent(QResizeEvent* event) @@ -172,9 +168,9 @@ void MainWindow::layoutPanels() m_bottomPanel->setGeometry(0, headerH + gameH, totalW, panelH); } -void MainWindow::onStateUpdated(Tick /*tick*/, int blocks, double /*speed*/) +void MainWindow::handleEvent(std::shared_ptr event) { - m_buildButtonGrid->updateAffordability(blocks); + m_buildButtonGrid->updateAffordability(event->blocks); } void MainWindow::onEscapeMenuRequested() diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 2c12d00..ad9f561 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -5,7 +5,9 @@ #include +#include "BuildingBlocksChangedEvent.h" #include "BuildingId.h" +#include "EventHandler.h" #include "ShipLayoutBlueprint.h" #include "Tick.h" #include "VisualsConfig.h" @@ -19,26 +21,29 @@ class BlueprintPanel; class QCloseEvent; class QResizeEvent; -class MainWindow : public QWidget +class MainWindow : public QWidget, + public EventHandler { Q_OBJECT public: MainWindow(Simulation* sim, const std::string& configDir, QWidget* parent = nullptr); + ~MainWindow() override; protected: void resizeEvent(QResizeEvent* event) override; void closeEvent(QCloseEvent* event) override; +private: + void handleEvent(std::shared_ptr event) override; + void layoutPanels(); + private slots: void onGameOver(); - void onStateUpdated(Tick tick, int blocks, double speed); void onEscapeMenuRequested(); void onLayoutDialogRequested(BuildingId shipyardId); private: - void layoutPanels(); - std::string m_configDir; VisualsConfig m_visuals; Simulation* m_sim; diff --git a/src/ui/SelectedBuildingPanel.cpp b/src/ui/SelectedBuildingPanel.cpp index de9aeef..6152c30 100644 --- a/src/ui/SelectedBuildingPanel.cpp +++ b/src/ui/SelectedBuildingPanel.cpp @@ -13,6 +13,7 @@ #include #include "BeltSystem.h" +#include "TickAdvancedEvent.h" #include "Building.h" #include "BuildingSystem.h" #include "BuildingType.h" @@ -136,6 +137,13 @@ SelectedBuildingPanel::SelectedBuildingPanel(Simulation* sim, this, &SelectedBuildingPanel::onSplitterFilterChanged); buildEmpty(); + + registerForEvent(); +} + +SelectedBuildingPanel::~SelectedBuildingPanel() +{ + unregisterForEvent(); } void SelectedBuildingPanel::onSelectionChanged(const std::vector& ids) @@ -488,7 +496,7 @@ const ShipDef* SelectedBuildingPanel::findShipDef(const std::string& id) const return nullptr; } -void SelectedBuildingPanel::onStateUpdated(Tick /*tick*/, int /*blocks*/, double /*speed*/) +void SelectedBuildingPanel::handleEvent(std::shared_ptr /*event*/) { if (m_singleBuildingId == kInvalidBuildingId) { return; } const Building* b = m_sim->buildings().findBuilding(m_singleBuildingId); diff --git a/src/ui/SelectedBuildingPanel.h b/src/ui/SelectedBuildingPanel.h index 337c854..272e6ea 100644 --- a/src/ui/SelectedBuildingPanel.h +++ b/src/ui/SelectedBuildingPanel.h @@ -8,11 +8,13 @@ #include "Building.h" #include "BuildingId.h" +#include "EventHandler.h" #include "GameConfig.h" #include "RecipesConfig.h" #include "ShipLayout.h" #include "ShipsConfig.h" #include "Tick.h" +#include "TickAdvancedEvent.h" class Simulation; class ShipLayoutPreview; @@ -22,20 +24,24 @@ class QListWidget; class QPushButton; class QVBoxLayout; -class SelectedBuildingPanel : public QWidget +class SelectedBuildingPanel : public QWidget, + public EventHandler { Q_OBJECT public: SelectedBuildingPanel(Simulation* sim, const GameConfig* config, QWidget* parent = nullptr); + ~SelectedBuildingPanel() override; signals: void layoutDialogRequested(BuildingId shipyardId); public slots: void onSelectionChanged(const std::vector& ids); - void onStateUpdated(Tick tick, int blocks, double speed); + +private: + void handleEvent(std::shared_ptr event) override; private slots: void onRecipeChanged(int comboIndex);