Merge branch 'eventManager' into diggingInvaders-unstable

develop
expwnent 2013-01-03 19:32:12 -05:00
commit f145f8d528
3 changed files with 45 additions and 62 deletions

@ -27,12 +27,13 @@ namespace DFHack {
struct EventHandler { struct EventHandler {
void (*eventHandler)(color_ostream&, void*); //called when the event happens void (*eventHandler)(color_ostream&, void*); //called when the event happens
int32_t freq;
EventHandler(void (*eventHandlerIn)(color_ostream&, void*)): eventHandler(eventHandlerIn) { EventHandler(void (*eventHandlerIn)(color_ostream&, void*), int32_t freqIn): eventHandler(eventHandlerIn), freq(freqIn) {
} }
bool operator==(EventHandler& handle) const { bool operator==(EventHandler& handle) const {
return eventHandler == handle.eventHandler; return eventHandler == handle.eventHandler && freq == handle.freq;
} }
bool operator!=(EventHandler& handle) const { bool operator!=(EventHandler& handle) const {
return !( *this == handle); return !( *this == handle);
@ -47,9 +48,9 @@ namespace DFHack {
} }
}; };
DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin); DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin);
DFHACK_EXPORT void registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false); DFHACK_EXPORT void registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false);
DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin); DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, Plugin* plugin);
DFHACK_EXPORT void unregisterAll(Plugin* plugin); DFHACK_EXPORT void unregisterAll(Plugin* plugin);
void manageEvents(color_ostream& out); void manageEvents(color_ostream& out);
void onStateChange(color_ostream& out, state_change_event event); void onStateChange(color_ostream& out, state_change_event event);

@ -36,16 +36,12 @@ multimap<uint32_t, EventHandler> tickQueue;
//TODO: consider unordered_map of pairs, or unordered_map of unordered_set, or whatever //TODO: consider unordered_map of pairs, or unordered_map of unordered_set, or whatever
multimap<Plugin*, EventHandler> handlers[EventType::EVENT_MAX]; 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]; uint32_t eventLastTick[EventType::EVENT_MAX];
const uint32_t ticksPerYear = 403200; const uint32_t ticksPerYear = 403200;
void DFHack::EventManager::registerListener(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin) { void DFHack::EventManager::registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin) {
handlers[e].insert(pair<Plugin*, EventHandler>(plugin, handler)); 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) { void DFHack::EventManager::registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute) {
@ -66,7 +62,7 @@ void DFHack::EventManager::registerTick(EventHandler handler, int32_t when, Plug
return; return;
} }
void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handler, int32_t freq, Plugin* plugin) { void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handler, Plugin* plugin) {
for ( multimap<Plugin*, EventHandler>::iterator i = handlers[e].find(plugin); i != handlers[e].end(); i++ ) { for ( multimap<Plugin*, EventHandler>::iterator i = handlers[e].find(plugin); i != handlers[e].end(); i++ ) {
if ( (*i).first != plugin ) if ( (*i).first != plugin )
break; break;
@ -76,16 +72,6 @@ void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handl
break; 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; return;
} }
@ -112,21 +98,6 @@ void DFHack::EventManager::unregisterAll(Plugin* plugin) {
for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) { for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) {
handlers[a].erase(plugin); 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; return;
} }
@ -171,8 +142,8 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event
if ( !doOnce ) { if ( !doOnce ) {
//TODO: put this somewhere else //TODO: put this somewhere else
doOnce = true; doOnce = true;
EventHandler buildingHandler(Buildings::updateBuildings); EventHandler buildingHandler(Buildings::updateBuildings, 100);
DFHack::EventManager::registerListener(EventType::BUILDING, buildingHandler, 100, NULL); DFHack::EventManager::registerListener(EventType::BUILDING, buildingHandler, NULL);
//out.print("Registered listeners.\n %d", __LINE__); //out.print("Registered listeners.\n %d", __LINE__);
} }
if ( event == DFHack::SC_MAP_UNLOADED ) { if ( event == DFHack::SC_MAP_UNLOADED ) {
@ -221,37 +192,48 @@ void DFHack::EventManager::manageEvents(color_ostream& out) {
if ( tick <= lastTick ) if ( tick <= lastTick )
return; return;
lastTick = tick; lastTick = tick;
int32_t eventFrequency[EventType::EVENT_MAX];
for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) {
int32_t min = 1000000000;
for ( auto b = handlers[a].begin(); b != handlers[a].end(); b++ ) {
EventHandler bob = (*b).second;
if ( bob.freq < min )
min = bob.freq;
}
eventFrequency[a] = min;
}
manageTickEvent(out); manageTickEvent(out);
if ( tick - eventLastTick[EventType::JOB_INITIATED] >= (*eventFrequency[EventType::JOB_INITIATED].begin()).first ) { if ( tick - eventLastTick[EventType::JOB_INITIATED] >= eventFrequency[EventType::JOB_INITIATED] ) {
manageJobInitiatedEvent(out); manageJobInitiatedEvent(out);
eventLastTick[EventType::JOB_INITIATED] = tick; eventLastTick[EventType::JOB_INITIATED] = tick;
} }
if ( tick - eventLastTick[EventType::JOB_COMPLETED] >= (*eventFrequency[EventType::JOB_COMPLETED].begin()).first ) { if ( tick - eventLastTick[EventType::JOB_COMPLETED] >= eventFrequency[EventType::JOB_COMPLETED] ) {
manageJobCompletedEvent(out); manageJobCompletedEvent(out);
eventLastTick[EventType::JOB_COMPLETED] = tick; eventLastTick[EventType::JOB_COMPLETED] = tick;
} }
if ( tick - eventLastTick[EventType::UNIT_DEATH] >= (*eventFrequency[EventType::UNIT_DEATH].begin()).first ) { if ( tick - eventLastTick[EventType::UNIT_DEATH] >= eventFrequency[EventType::UNIT_DEATH] ) {
manageUnitDeathEvent(out); manageUnitDeathEvent(out);
eventLastTick[EventType::UNIT_DEATH] = tick; eventLastTick[EventType::UNIT_DEATH] = tick;
} }
if ( tick - eventLastTick[EventType::ITEM_CREATED] >= (*eventFrequency[EventType::ITEM_CREATED].begin()).first ) { if ( tick - eventLastTick[EventType::ITEM_CREATED] >= eventFrequency[EventType::ITEM_CREATED] ) {
manageItemCreationEvent(out); manageItemCreationEvent(out);
eventLastTick[EventType::ITEM_CREATED] = tick; eventLastTick[EventType::ITEM_CREATED] = tick;
} }
if ( tick - eventLastTick[EventType::BUILDING] >= (*eventFrequency[EventType::BUILDING].begin()).first ) { if ( tick - eventLastTick[EventType::BUILDING] >= eventFrequency[EventType::BUILDING] ) {
manageBuildingEvent(out); manageBuildingEvent(out);
eventLastTick[EventType::BUILDING] = tick; eventLastTick[EventType::BUILDING] = tick;
} }
if ( tick - eventLastTick[EventType::CONSTRUCTION] >= (*eventFrequency[EventType::CONSTRUCTION].begin()).first ) { if ( tick - eventLastTick[EventType::CONSTRUCTION] >= eventFrequency[EventType::CONSTRUCTION] ) {
manageConstructionEvent(out); manageConstructionEvent(out);
eventLastTick[EventType::CONSTRUCTION] = tick; eventLastTick[EventType::CONSTRUCTION] = tick;
} }
if ( tick - eventLastTick[EventType::SYNDROME] >= (*eventFrequency[EventType::SYNDROME].begin()).first ) { if ( tick - eventLastTick[EventType::SYNDROME] >= eventFrequency[EventType::SYNDROME] ) {
manageSyndromeEvent(out); manageSyndromeEvent(out);
eventLastTick[EventType::SYNDROME] = tick; eventLastTick[EventType::SYNDROME] = tick;
} }
if ( tick - eventLastTick[EventType::INVASION] >= (*eventFrequency[EventType::INVASION].begin()).first ) { if ( tick - eventLastTick[EventType::INVASION] >= eventFrequency[EventType::INVASION] ) {
manageInvasionEvent(out); manageInvasionEvent(out);
eventLastTick[EventType::INVASION] = tick; eventLastTick[EventType::INVASION] = tick;
} }

@ -34,30 +34,30 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector<PluginC
} }
command_result eventExample(color_ostream& out, vector<string>& parameters) { command_result eventExample(color_ostream& out, vector<string>& parameters) {
EventManager::EventHandler initiateHandler(jobInitiated); EventManager::EventHandler initiateHandler(jobInitiated, 10);
EventManager::EventHandler completeHandler(jobCompleted); EventManager::EventHandler completeHandler(jobCompleted, 5);
EventManager::EventHandler timeHandler(timePassed); EventManager::EventHandler timeHandler(timePassed, 1);
EventManager::EventHandler deathHandler(unitDeath); EventManager::EventHandler deathHandler(unitDeath, 500);
EventManager::EventHandler itemHandler(itemCreate); EventManager::EventHandler itemHandler(itemCreate, 1000);
EventManager::EventHandler buildingHandler(building); EventManager::EventHandler buildingHandler(building, 500);
EventManager::EventHandler constructionHandler(construction); EventManager::EventHandler constructionHandler(construction, 100);
EventManager::EventHandler syndromeHandler(syndrome); EventManager::EventHandler syndromeHandler(syndrome, 1);
EventManager::EventHandler invasionHandler(invasion); EventManager::EventHandler invasionHandler(invasion, 1000);
Plugin* me = Core::getInstance().getPluginManager()->getPluginByName("eventExample"); Plugin* me = Core::getInstance().getPluginManager()->getPluginByName("eventExample");
EventManager::unregisterAll(me); EventManager::unregisterAll(me);
EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, 10, me); EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, me);
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, 5, me); EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, me);
EventManager::registerTick(timeHandler, 1, me); EventManager::registerTick(timeHandler, 1, me);
EventManager::registerTick(timeHandler, 2, me); EventManager::registerTick(timeHandler, 2, me);
EventManager::registerTick(timeHandler, 4, me); EventManager::registerTick(timeHandler, 4, me);
EventManager::registerTick(timeHandler, 8, me); EventManager::registerTick(timeHandler, 8, me);
EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, 500, me); EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, me);
EventManager::registerListener(EventManager::EventType::ITEM_CREATED, itemHandler, 1000, me); EventManager::registerListener(EventManager::EventType::ITEM_CREATED, itemHandler, me);
EventManager::registerListener(EventManager::EventType::BUILDING, buildingHandler, 500, me); EventManager::registerListener(EventManager::EventType::BUILDING, buildingHandler, me);
EventManager::registerListener(EventManager::EventType::CONSTRUCTION, constructionHandler, 100, me); EventManager::registerListener(EventManager::EventType::CONSTRUCTION, constructionHandler, me);
EventManager::registerListener(EventManager::EventType::SYNDROME, syndromeHandler, 1, me); EventManager::registerListener(EventManager::EventType::SYNDROME, syndromeHandler, me);
EventManager::registerListener(EventManager::EventType::INVASION, invasionHandler, 1, me); EventManager::registerListener(EventManager::EventType::INVASION, invasionHandler, me);
out.print("Events registered.\n"); out.print("Events registered.\n");
return CR_OK; return CR_OK;
} }