Permalink
Browse files

[Performance] Fixed an overhead issue where many hot paths would trig…

…ger quest subroutines and beneath that the code would try to see if a quest existed perpetually (checking if file exists) even though it should have determined the quest didn't exist the first time.

- This caused a lot of overhead in an instance where an entire zone of NPC's is pathing, triggering EVENT_WAYPOINT_ARRIVE and EVENT_WAYPOINT_DEPART when there is no global_npc.pl/lua, or all NPC's pathing don't have a quest assigned, similar behavior would occur. This goes for any other type of quests: spells, items, encounters etc.
  • Loading branch information...
Akkadius committed Mar 30, 2017
1 parent f5f2cbc commit 9d0308c9bf844fc0f9579d540f24cfaa7de19c69
Showing with 26 additions and 11 deletions.
  1. +8 −0 changelog.txt
  2. +18 −11 zone/quest_parser_collection.cpp
View
@@ -1,5 +1,13 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 03/30/2017 ==
Akkadius: [Performance] Fixed an overhead issue where many hot paths would trigger quest subroutines and beneath that the code would
try to see if a quest existed perpetually (checking if file exists) even though it should have determined the quest
didn't exist the first time.
- This caused a lot of overhead in an instance where an entire zone of NPC's is pathing, triggering EVENT_WAYPOINT_ARRIVE
and EVENT_WAYPOINT_DEPART when there is no global_npc.pl/lua, or all NPC's pathing don't have a quest assigned, similar
behavior would occur. This goes for any other type of quests: spells, items, encounters etc.
== 03/28/2017 ==
Akkadius: [Performance] Fixed a large overhead issue where every single NPC in a zone was checking to depop themselves
as a swarm pet every 3ms regardless of being a swarm pet or not. Swarm pets now check to depop only when their timer is up
@@ -16,6 +16,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/global_define.h"
#include "../common/misc_functions.h"
#include "../common/features.h"
@@ -186,7 +187,7 @@ bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt)
auto qiter = _interfaces.find(iter->second);
return qiter->second->SpellHasQuestSub(spell_id, evt);
}
} else {
} else if(_spell_quest_status[spell_id] != QuestFailedToLoad){
std::string filename;
QuestInterface *qi = GetQIBySpellQuest(spell_id, filename);
if(qi) {
@@ -263,7 +264,7 @@ int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init,
auto qiter = _interfaces.find(iter->second);
return qiter->second->EventNPC(evt, npc, init, data, extra_data, extra_pointers);
}
} else {
} else if (_npc_quest_status[npc->GetNPCTypeID()] != QuestFailedToLoad){
std::string filename;
QuestInterface *qi = GetQIByNPCQuest(npc->GetNPCTypeID(), filename);
if(qi) {
@@ -282,7 +283,8 @@ int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init,
if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) {
auto qiter = _interfaces.find(_global_npc_quest_status);
return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers);
} else {
}
else if(_global_npc_quest_status != QuestFailedToLoad){
std::string filename;
QuestInterface *qi = GetQIByGlobalNPCQuest(filename);
if(qi) {
@@ -380,7 +382,7 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, EQEmu::It
return ret;
}
return DispatchEventItem(evt, client, item, mob, data, extra_data, extra_pointers);
} else {
} else if(_item_quest_status[item_id] != QuestFailedToLoad){
std::string filename;
QuestInterface *qi = GetQIByItemQuest(item_script, filename);
if(qi) {
@@ -415,19 +417,21 @@ int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client
return ret;
}
return DispatchEventSpell(evt, npc, client, spell_id, extra_data, extra_pointers);
} else {
}
else if (_spell_quest_status[spell_id] != QuestFailedToLoad) {
std::string filename;
QuestInterface *qi = GetQIBySpellQuest(spell_id, filename);
if(qi) {
if (qi) {
_spell_quest_status[spell_id] = qi->GetIdentifier();
qi->LoadSpellScript(filename, spell_id);
int ret = DispatchEventSpell(evt, npc, client, spell_id, extra_data, extra_pointers);
int i = qi->EventSpell(evt, npc, client, spell_id, extra_data, extra_pointers);
if(i != 0) {
ret = i;
}
if (i != 0) {
ret = i;
}
return ret;
} else {
}
else {
_spell_quest_status[spell_id] = QuestFailedToLoad;
return DispatchEventSpell(evt, npc, client, spell_id, extra_data, extra_pointers);
}
@@ -444,7 +448,7 @@ int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounte
auto qiter = _interfaces.find(iter->second);
return qiter->second->EventEncounter(evt, encounter_name, data, extra_data, extra_pointers);
}
} else {
} else if(_encounter_quest_status[encounter_name] != QuestFailedToLoad){
std::string filename;
QuestInterface *qi = GetQIByEncounterQuest(encounter_name, filename);
if(qi) {
@@ -695,12 +699,15 @@ QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filena
std::string tmp;
FILE *f = nullptr;
auto iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
auto ext = _extensions.find((*iter)->GetIdentifier());
tmp += ".";
tmp += ext->second;
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);

0 comments on commit 9d0308c

Please sign in to comment.