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 <string>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <array>
using namespace std; using namespace std;
using namespace DFHack; using namespace DFHack;
@ -140,24 +141,58 @@ static void manageInteractionEvent(color_ostream& out);
typedef void (*eventManager_t)(color_ostream&); typedef void (*eventManager_t)(color_ostream&);
static const eventManager_t eventManager[] = { // integrate new events into this function, and no longer worry about syncing the enum list with the `eventManager` array
manageTickEvent, eventManager_t getManager(EventType::EventType t) {
manageJobInitiatedEvent, switch (t) {
manageJobStartedEvent, case EventType::TICK:
manageJobCompletedEvent, return manageTickEvent;
manageNewUnitActiveEvent, case EventType::JOB_INITIATED:
manageUnitDeathEvent, return manageJobInitiatedEvent;
manageItemCreationEvent, case EventType::JOB_STARTED:
manageBuildingEvent, return manageJobStartedEvent;
manageConstructionEvent, case EventType::JOB_COMPLETED:
manageSyndromeEvent, return manageJobCompletedEvent;
manageInvasionEvent, case EventType::UNIT_NEW_ACTIVE:
manageEquipmentEvent, return manageNewUnitActiveEvent;
manageReportEvent, case EventType::UNIT_DEATH:
manageUnitAttackEvent, return manageUnitDeathEvent;
manageUnloadEvent, case EventType::ITEM_CREATED:
manageInteractionEvent, 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 //job initiated
static int32_t lastJobId = -1; 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) { void DFHack::EventManager::manageEvents(color_ostream& out) {
static const std::array<eventManager_t, EventType::EVENT_MAX> eventManager = compileManagerArray();
if ( !gameLoaded ) { if ( !gameLoaded ) {
return; return;
} }

@ -28,6 +28,7 @@
#include <string.h> #include <string.h>
#include <stdexcept> #include <stdexcept>
#include <array>
using std::vector; using std::vector;
using std::string; 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); std::vector<int> enabledEventManagerEvents(EventManager::EventType::EVENT_MAX,-1);
typedef void (*handler_t) (color_ostream&,void*); typedef void (*handler_t) (color_ostream&,void*);
// NOTICE: keep this list synchronized with the EventManager::EventType enum or using namespace EventManager::EventType;
// else the wrong event handlers will get called. // integrate new events into this function, and no longer worry about syncing with the enum list
static const handler_t eventHandlers[] = { handler_t getManager(EventType t) {
NULL, switch (t) {
ev_mng_jobInitiated, case TICK:
ev_mng_jobStarted, return nullptr;
ev_mng_jobCompleted, case JOB_INITIATED:
ev_mng_unitNewActive, return ev_mng_jobInitiated;
ev_mng_unitDeath, case JOB_STARTED:
ev_mng_itemCreate, return ev_mng_jobStarted;
ev_mng_building, case JOB_COMPLETED:
ev_mng_construction, return ev_mng_jobCompleted;
ev_mng_syndrome, case UNIT_NEW_ACTIVE:
ev_mng_invasion, return ev_mng_unitNewActive;
ev_mng_inventory, case UNIT_DEATH:
ev_mng_report, return ev_mng_unitDeath;
ev_mng_unitAttack, case ITEM_CREATED:
ev_mng_unload, return ev_mng_itemCreate;
ev_mng_interaction, 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) static void enableEvent(int evType,int freq)
{ {
if (freq < 0) 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) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
eventHandlers = compileEventHandlerArray();
if (Core::getInstance().isWorldLoaded()) if (Core::getInstance().isWorldLoaded())
plugin_onstatechange(out, SC_WORLD_LOADED); plugin_onstatechange(out, SC_WORLD_LOADED);
enable_hooks(true); enable_hooks(true);