EventManager: allowed plugins to specify how often they need events to be checked, in the event that monitoring is necessary.

develop
expwnent 2013-01-02 11:07:56 -05:00
parent fa78d6ccfc
commit c3b2ae2137
3 changed files with 66 additions and 17 deletions

@ -37,9 +37,9 @@ namespace DFHack {
}
};
DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin);
DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin);
DFHACK_EXPORT void registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false);
DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, Plugin* plugin);
DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin);
DFHACK_EXPORT void unregisterAll(Plugin* plugin);
void manageEvents(color_ostream& out);
void onStateChange(color_ostream& out, state_change_event event);

@ -34,11 +34,16 @@ multimap<uint32_t, EventHandler> tickQueue;
//TODO: consider unordered_map of pairs, or unordered_map of unordered_set, or whatever
multimap<Plugin*, EventHandler> handlers[EventType::EVENT_MAX];
multimap<Plugin*, int32_t> pluginFrequencies[EventType::EVENT_MAX];
map<int32_t, int32_t> eventFrequency[EventType::EVENT_MAX];
uint32_t eventLastTick[EventType::EVENT_MAX];
const uint32_t ticksPerYear = 403200;
void DFHack::EventManager::registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin) {
void DFHack::EventManager::registerListener(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin) {
handlers[e].insert(pair<Plugin*, EventHandler>(plugin, handler));
eventFrequency[e][freq]++;
pluginFrequencies[e].insert(pair<Plugin*,int32_t>(plugin, freq));
}
void DFHack::EventManager::registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute) {
@ -59,7 +64,7 @@ void DFHack::EventManager::registerTick(EventHandler handler, int32_t when, Plug
return;
}
void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handler, Plugin* plugin) {
void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin) {
for ( multimap<Plugin*, EventHandler>::iterator i = handlers[e].find(plugin); i != handlers[e].end(); i++ ) {
if ( (*i).first != plugin )
break;
@ -69,6 +74,16 @@ void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handl
break;
}
}
if ( eventFrequency[e].find(freq) == eventFrequency[e].end() ) {
Core::getInstance().getConsole().print("%s, line %d: Error: incorrect frequency on deregister.\n", __FILE__, __LINE__);
return;
}
eventFrequency[e][freq]--;
if ( eventFrequency[e][freq] == 0 ) {
eventFrequency[e].erase(eventFrequency[e].find(freq));
} else if ( eventFrequency[e][freq] < 0 ) {
Core::getInstance().getConsole().print("%s, line %d: Error: incorrect frequency on deregister.\n", __FILE__, __LINE__);
}
return;
}
@ -95,6 +110,21 @@ void DFHack::EventManager::unregisterAll(Plugin* plugin) {
for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) {
handlers[a].erase(plugin);
}
for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) {
for ( auto b = pluginFrequencies[a].begin(); b != pluginFrequencies[a].end(); b++ ) {
if ( (*b).first != plugin )
continue;
int32_t freq = (*b).second;
eventFrequency[a][freq]--;
if ( eventFrequency[a][freq] < 0 ) {
Core::getInstance().getConsole().print("%s, line %d: Error: incorrect frequency on deregister.\n", __FILE__, __LINE__);
eventFrequency[a].erase(eventFrequency[a].find(freq));
} else if ( eventFrequency[a][freq] == 0 ) {
eventFrequency[a].erase(eventFrequency[a].find(freq));
}
}
}
return;
}
@ -134,7 +164,7 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event
//TODO: put this somewhere else
doOnce = true;
EventHandler buildingHandler(Buildings::updateBuildings);
DFHack::EventManager::registerListener(EventType::BUILDING, buildingHandler, NULL);
DFHack::EventManager::registerListener(EventType::BUILDING, buildingHandler, 100, NULL);
//out.print("Registered listeners.\n %d", __LINE__);
}
if ( event == DFHack::SC_MAP_UNLOADED ) {
@ -175,17 +205,36 @@ void DFHack::EventManager::manageEvents(color_ostream& out) {
}
uint32_t tick = DFHack::World::ReadCurrentYear()*ticksPerYear
+ DFHack::World::ReadCurrentTick();
if ( tick <= lastTick )
return;
lastTick = tick;
manageTickEvent(out);
manageJobInitiatedEvent(out);
manageJobCompletedEvent(out);
manageUnitDeathEvent(out);
manageItemCreationEvent(out);
manageBuildingEvent(out);
manageConstructionEvent(out);
if ( tick - eventLastTick[EventType::JOB_INITIATED] >= (*eventFrequency[EventType::JOB_INITIATED].begin()).first ) {
manageJobInitiatedEvent(out);
eventLastTick[EventType::JOB_INITIATED] = tick;
}
if ( tick - eventLastTick[EventType::JOB_COMPLETED] >= (*eventFrequency[EventType::JOB_COMPLETED].begin()).first ) {
manageJobCompletedEvent(out);
eventLastTick[EventType::JOB_COMPLETED] = tick;
}
if ( tick - eventLastTick[EventType::UNIT_DEATH] >= (*eventFrequency[EventType::UNIT_DEATH].begin()).first ) {
manageUnitDeathEvent(out);
eventLastTick[EventType::UNIT_DEATH] = tick;
}
if ( tick - eventLastTick[EventType::ITEM_CREATED] >= (*eventFrequency[EventType::ITEM_CREATED].begin()).first ) {
manageItemCreationEvent(out);
eventLastTick[EventType::ITEM_CREATED] = tick;
}
if ( tick - eventLastTick[EventType::BUILDING] >= (*eventFrequency[EventType::BUILDING].begin()).first ) {
manageBuildingEvent(out);
eventLastTick[EventType::BUILDING] = tick;
}
if ( tick - eventLastTick[EventType::CONSTRUCTION] >= (*eventFrequency[EventType::CONSTRUCTION].begin()).first ) {
manageConstructionEvent(out);
eventLastTick[EventType::CONSTRUCTION] = tick;
}
return;
}

@ -43,16 +43,16 @@ command_result eventExample(color_ostream& out, vector<string>& parameters) {
Plugin* me = Core::getInstance().getPluginManager()->getPluginByName("eventExample");
EventManager::unregisterAll(me);
EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, me);
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, me);
EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, 10, me);
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, 5, me);
EventManager::registerTick(timeHandler, 1, me);
EventManager::registerTick(timeHandler, 2, me);
EventManager::registerTick(timeHandler, 4, me);
EventManager::registerTick(timeHandler, 8, me);
EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, me);
EventManager::registerListener(EventManager::EventType::ITEM_CREATED, itemHandler, me);
EventManager::registerListener(EventManager::EventType::BUILDING, buildingHandler, me);
EventManager::registerListener(EventManager::EventType::CONSTRUCTION, constructionHandler, me);
EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, 500, me);
EventManager::registerListener(EventManager::EventType::ITEM_CREATED, itemHandler, 1000, me);
EventManager::registerListener(EventManager::EventType::BUILDING, buildingHandler, 500, me);
EventManager::registerListener(EventManager::EventType::CONSTRUCTION, constructionHandler, 100, me);
out.print("Events registered.\n");
return CR_OK;
}