Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EventManager/Eventful - Generate event arrays #2097

Merged
merged 4 commits into from
Apr 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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