From f99c33b48c5afb05ec1ae90a5f13bd971e92c9bb Mon Sep 17 00:00:00 2001 From: dP Date: Tue, 7 Jul 2020 21:27:51 +0300 Subject: [PATCH] Add event slots --- src/citymania/cm_event.hpp | 31 +++++++++++++++++++++++-------- src/citymania/cm_game.cpp | 18 +++++++++--------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/citymania/cm_event.hpp b/src/citymania/cm_event.hpp index b699ae4e93..2a5fe1eb7c 100644 --- a/src/citymania/cm_event.hpp +++ b/src/citymania/cm_event.hpp @@ -2,6 +2,8 @@ #define CM_EVENT_HPP #include "cm_type.hpp" + +#include "../console_func.h" #include "../cargo_type.h" #include "../company_type.h" #include "../economy_type.h" @@ -104,6 +106,12 @@ struct CompanyBalanceChanged { Money delta; }; +enum class Slot : uint8 { + CONTROLLER = 10, + GAME = 20, + CONTROLLER_POST = 30, + RECORDER = 40, +}; class TypeDispatcherBase { public: @@ -119,14 +127,20 @@ public: TypeDispatcher() { } virtual ~TypeDispatcher() {} - void listen(Handler &handler) { - this->new_handlers.push_back(handler); + void listen(Slot slot, Handler &handler) { + auto p = this->handler_map.find(slot); + if (p != this->handler_map.end()) + IConsolePrintF(CC_ERROR, "ERROR: Ignored duplicate handler for event %s slot %d", typeid(T).name(), (int)slot); + this->handler_map.insert(p, std::make_pair(slot, handler)); + this->new_handlers = true; } void emit(const T &event) { - if (!this->new_handlers.empty()) { - this->handlers.insert(this->handlers.end(), this->new_handlers.begin(), this->new_handlers.end()); - this->new_handlers.clear(); + if (this->new_handlers) { // only rebuild handlers while not iterating + this->handlers.clear(); + for (auto &p : this->handler_map) { + this->handlers.push_back(p.second); + } } for (auto &h : this->handlers) { h(event); @@ -135,7 +149,8 @@ public: protected: std::vector handlers; - std::vector new_handlers; + std::map handler_map; + bool new_handlers = false; }; @@ -155,8 +170,8 @@ protected: public: template - void listen(std::function handler) { - this->get_dispatcher().listen(handler); + void listen(Slot slot, std::function handler) { + this->get_dispatcher().listen(slot, handler); } template diff --git a/src/citymania/cm_game.cpp b/src/citymania/cm_game.cpp index 1a64748333..c4e035daef 100644 --- a/src/citymania/cm_game.cpp +++ b/src/citymania/cm_game.cpp @@ -9,7 +9,7 @@ namespace citymania { Game::Game() { - this->events.listen([this] (const event::NewMonth &) { + this->events.listen(event::Slot::GAME, [this] (const event::NewMonth &) { for (Town *t : Town::Iterate()) { t->cm.hs_last_month = t->cm.hs_total - t->cm.hs_total_prev; t->cm.hs_total_prev = t->cm.hs_total; @@ -28,19 +28,19 @@ Game::Game() { this->towns_growth_tiles.clear(); }); - this->events.listen([this] (const event::TownGrowthSucceeded &event) { + this->events.listen(event::Slot::GAME, [this] (const event::TownGrowthSucceeded &event) { if (event.town->cache.num_houses <= event.prev_houses) { event.town->cm.hs_total++; this->set_town_growth_tile(event.tile, TownGrowthTileState::HS); } }); - this->events.listen([this] (const event::TownGrowthFailed &event) { + this->events.listen(event::Slot::GAME, [this] (const event::TownGrowthFailed &event) { event.town->cm.cs_total++; this->set_town_growth_tile(event.tile, TownGrowthTileState::CS); }); - this->events.listen([this] (const event::HouseRebuilt &event) { + this->events.listen(event::Slot::GAME, [this] (const event::HouseRebuilt &event) { if (event.was_successful) { event.town->cm.houses_reconstructed_this_month++; this->set_town_growth_tile(event.tile, TownGrowthTileState::RH_REBUILT); @@ -50,23 +50,23 @@ Game::Game() { } }); - this->events.listen([this] (const event::HouseBuilt &event) { + this->events.listen(event::Slot::GAME, [this] (const event::HouseBuilt &event) { event.town->cm.houses_constructing++; event.town->cm.real_population += event.house_spec->population; this->set_town_growth_tile(event.tile, TownGrowthTileState::NEW_HOUSE); }); - this->events.listen([this] (const event::HouseCleared &event) { + this->events.listen(event::Slot::GAME, [this] (const event::HouseCleared &event) { if (!event.was_completed) event.town->cm.houses_constructing--; event.town->cm.real_population -= event.house_spec->population; }); - this->events.listen([this] (const event::HouseCompleted &event) { + this->events.listen(event::Slot::GAME, [this] (const event::HouseCompleted &event) { event.town->cm.houses_constructing--; }); - this->events.listen([this] (const event::TownCachesRebuilt &event) { + this->events.listen(event::Slot::GAME, [this] (const event::TownCachesRebuilt &event) { for (Town *town : Town::Iterate()) { town->cm.real_population = 0; town->cm.houses_constructing = 0; @@ -81,7 +81,7 @@ Game::Game() { } }); - this->events.listen([this] (const event::CargoAccepted &event) { + this->events.listen(event::Slot::GAME, [this] (const event::CargoAccepted &event) { event.company->cur_economy.cm.cargo_income[event.cargo_type] += event.profit; }); }