Add event slots

This commit is contained in:
dP
2020-07-07 21:27:51 +03:00
parent ee7d3c9df8
commit f99c33b48c
2 changed files with 32 additions and 17 deletions

View File

@@ -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<Handler> handlers;
std::vector<Handler> new_handlers;
std::map<Slot, Handler> handler_map;
bool new_handlers = false;
};
@@ -155,8 +170,8 @@ protected:
public:
template<typename T>
void listen(std::function<void(const T &)> handler) {
this->get_dispatcher<T>().listen(handler);
void listen(Slot slot, std::function<void(const T &)> handler) {
this->get_dispatcher<T>().listen(slot, handler);
}
template<typename T>

View File

@@ -9,7 +9,7 @@
namespace citymania {
Game::Game() {
this->events.listen<event::NewMonth>([this] (const event::NewMonth &) {
this->events.listen<event::NewMonth>(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<event::TownGrowthSucceeded>([this] (const event::TownGrowthSucceeded &event) {
this->events.listen<event::TownGrowthSucceeded>(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<event::TownGrowthFailed>([this] (const event::TownGrowthFailed &event) {
this->events.listen<event::TownGrowthFailed>(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<event::HouseRebuilt>([this] (const event::HouseRebuilt &event) {
this->events.listen<event::HouseRebuilt>(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<event::HouseBuilt>([this] (const event::HouseBuilt &event) {
this->events.listen<event::HouseBuilt>(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<event::HouseCleared>([this] (const event::HouseCleared &event) {
this->events.listen<event::HouseCleared>(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<event::HouseCompleted>([this] (const event::HouseCompleted &event) {
this->events.listen<event::HouseCompleted>(event::Slot::GAME, [this] (const event::HouseCompleted &event) {
event.town->cm.houses_constructing--;
});
this->events.listen<event::TownCachesRebuilt>([this] (const event::TownCachesRebuilt &event) {
this->events.listen<event::TownCachesRebuilt>(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<event::CargoAccepted>([this] (const event::CargoAccepted &event) {
this->events.listen<event::CargoAccepted>(event::Slot::GAME, [this] (const event::CargoAccepted &event) {
event.company->cur_economy.cm.cargo_income[event.cargo_type] += event.profit;
});
}