EventManager/Eventful - Generate event arrays (#2097)

* Replaces EventManager.cpp's event array with an auto-gen one

* Replaces eventful.cpp's event array with auto-gen one
develop
Josh Cooper 2022-04-14 21:47:25 -07:00 committed by GitHub
parent 5f3d5bbcd5
commit 9bf9a79a11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 111 additions and 38 deletions

@ -41,6 +41,7 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <array>
using namespace std;
using namespace DFHack;
@ -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;
@ -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;
}

@ -28,6 +28,7 @@
#include <string.h>
#include <stdexcept>
#include <array>
using std::vector;
using std::string;
@ -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)
@ -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);