Skip to content

Commit

Permalink
EventManager/Eventful - Generate event arrays (#2097)
Browse files Browse the repository at this point in the history
* Replaces EventManager.cpp's event array with an auto-gen one

* Replaces eventful.cpp's event array with auto-gen one
  • Loading branch information
cppcooper committed Apr 15, 2022
1 parent 5f3d5bb commit 9bf9a79
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 38 deletions.
72 changes: 54 additions & 18 deletions library/modules/EventManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <array>

using namespace std;
using namespace DFHack;
Expand Down Expand Up @@ -140,24 +141,58 @@ static void manageInteractionEvent(color_ostream& out);

typedef void (*eventManager_t)(color_ostream&);

static const eventManager_t eventManager[] = {
manageTickEvent,
manageJobInitiatedEvent,
manageJobStartedEvent,
manageJobCompletedEvent,
manageNewUnitActiveEvent,
manageUnitDeathEvent,
manageItemCreationEvent,
manageBuildingEvent,
manageConstructionEvent,
manageSyndromeEvent,
manageInvasionEvent,
manageEquipmentEvent,
manageReportEvent,
manageUnitAttackEvent,
manageUnloadEvent,
manageInteractionEvent,
};
// integrate new events into this function, and no longer worry about syncing the enum list with the `eventManager` array
eventManager_t getManager(EventType::EventType t) {
switch (t) {
case EventType::TICK:
return manageTickEvent;
case EventType::JOB_INITIATED:
return manageJobInitiatedEvent;
case EventType::JOB_STARTED:
return manageJobStartedEvent;
case EventType::JOB_COMPLETED:
return manageJobCompletedEvent;
case EventType::UNIT_NEW_ACTIVE:
return manageNewUnitActiveEvent;
case EventType::UNIT_DEATH:
return manageUnitDeathEvent;
case EventType::ITEM_CREATED:
return manageItemCreationEvent;
case EventType::BUILDING:
return manageBuildingEvent;
case EventType::CONSTRUCTION:
return manageConstructionEvent;
case EventType::SYNDROME:
return manageSyndromeEvent;
case EventType::INVASION:
return manageInvasionEvent;
case EventType::INVENTORY_CHANGE:
return manageEquipmentEvent;
case EventType::REPORT:
return manageReportEvent;
case EventType::UNIT_ATTACK:
return manageUnitAttackEvent;
case EventType::UNLOAD:
return manageUnloadEvent;
case EventType::INTERACTION:
return manageInteractionEvent;
case EventType::EVENT_MAX:
return nullptr;
//default:
//we don't do this... because then the compiler wouldn't error for missing cases in the enum
}
return nullptr;
}

std::array<eventManager_t,EventType::EVENT_MAX> compileManagerArray() {
std::array<eventManager_t, EventType::EVENT_MAX> managers{};
auto t = (EventType::EventType) 0;
while (t < EventType::EVENT_MAX) {
managers[t] = getManager(t);
t = (EventType::EventType) int(t + 1);
}
return managers;
}

//job initiated
static int32_t lastJobId = -1;
Expand Down Expand Up @@ -312,6 +347,7 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event
}

void DFHack::EventManager::manageEvents(color_ostream& out) {
static const std::array<eventManager_t, EventType::EVENT_MAX> eventManager = compileManagerArray();
if ( !gameLoaded ) {
return;
}
Expand Down
77 changes: 57 additions & 20 deletions plugins/eventful.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <string.h>
#include <stdexcept>
#include <array>

using std::vector;
using std::string;
Expand Down Expand Up @@ -223,26 +224,61 @@ static void ev_mng_interaction(color_ostream& out, void* ptr) {
std::vector<int> enabledEventManagerEvents(EventManager::EventType::EVENT_MAX,-1);
typedef void (*handler_t) (color_ostream&,void*);

// NOTICE: keep this list synchronized with the EventManager::EventType enum or
// else the wrong event handlers will get called.
static const handler_t eventHandlers[] = {
NULL,
ev_mng_jobInitiated,
ev_mng_jobStarted,
ev_mng_jobCompleted,
ev_mng_unitNewActive,
ev_mng_unitDeath,
ev_mng_itemCreate,
ev_mng_building,
ev_mng_construction,
ev_mng_syndrome,
ev_mng_invasion,
ev_mng_inventory,
ev_mng_report,
ev_mng_unitAttack,
ev_mng_unload,
ev_mng_interaction,
};
using namespace EventManager::EventType;
// integrate new events into this function, and no longer worry about syncing with the enum list
handler_t getManager(EventType t) {
switch (t) {
case TICK:
return nullptr;
case JOB_INITIATED:
return ev_mng_jobInitiated;
case JOB_STARTED:
return ev_mng_jobStarted;
case JOB_COMPLETED:
return ev_mng_jobCompleted;
case UNIT_NEW_ACTIVE:
return ev_mng_unitNewActive;
case UNIT_DEATH:
return ev_mng_unitDeath;
case ITEM_CREATED:
return ev_mng_itemCreate;
case BUILDING:
return ev_mng_building;
case CONSTRUCTION:
return ev_mng_construction;
case SYNDROME:
return ev_mng_syndrome;
case INVASION:
return ev_mng_invasion;
case INVENTORY_CHANGE:
return ev_mng_inventory;
case REPORT:
return ev_mng_report;
case UNIT_ATTACK:
return ev_mng_unitAttack;
case UNLOAD:
return ev_mng_unload;
case INTERACTION:
return ev_mng_interaction;
case EVENT_MAX:
return nullptr;
//default:
//we don't do this... because then the compiler wouldn't error for missing cases in the enum
}
return nullptr;
}

std::array<handler_t,EventManager::EventType::EVENT_MAX> compileEventHandlerArray() {
std::array<handler_t, EventManager::EventType::EVENT_MAX> managers{};
auto t = (EventManager::EventType::EventType) 0;
while (t < EventManager::EventType::EVENT_MAX) {
managers[t] = getManager(t);
t = (EventManager::EventType::EventType) int(t + 1);
}
return managers;
}
static std::array<handler_t,EventManager::EventType::EVENT_MAX> eventHandlers;

static void enableEvent(int evType,int freq)
{
if (freq < 0)
Expand Down Expand Up @@ -483,6 +519,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan

DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
eventHandlers = compileEventHandlerArray();
if (Core::getInstance().isWorldLoaded())
plugin_onstatechange(out, SC_WORLD_LOADED);
enable_hooks(true);
Expand Down

0 comments on commit 9bf9a79

Please sign in to comment.