- attempt to improve performance when units are blocked badly (this is not backwards compatible with other builds, will create out of synch)
This commit is contained in:
parent
b8f594fcf2
commit
c63da54bbd
|
@ -218,7 +218,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
}
|
||||
}
|
||||
|
||||
if(path->isStuck() == true && unit->getLastStuckPos() == finalPos &&
|
||||
if(path->isStuck() == true &&
|
||||
(unit->getLastStuckPos() == finalPos || path->getBlockCount() > 500) &&
|
||||
unit->isLastStuckFrameWithinCurrentFrameTolerance() == true) {
|
||||
|
||||
//printf("$$$$ Unit STILL BLOCKED for [%d - %s]\n",unit->getId(),unit->getFullName().c_str());
|
||||
|
@ -1418,6 +1419,31 @@ int PathFinder::findNodeIndex(Node *node, std::vector<Node> &nodeList) {
|
|||
return index;
|
||||
}
|
||||
|
||||
bool PathFinder::unitCannotMove(Unit *unit) {
|
||||
bool unitImmediatelyBlocked = false;
|
||||
|
||||
// First check if unit currently blocked all around them, if so don't try to pathfind
|
||||
const bool showConsoleDebugInfo = Config::getInstance().getBool("EnablePathfinderDistanceOutput","false");
|
||||
const Vec2i unitPos = unit->getPos();
|
||||
int failureCount = 0;
|
||||
int cellCount = 0;
|
||||
|
||||
for(int i = -1; i <= 1; ++i) {
|
||||
for(int j = -1; j <= 1; ++j) {
|
||||
Vec2i pos = unitPos + Vec2i(i, j);
|
||||
if(pos != unitPos) {
|
||||
bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos);
|
||||
if(canUnitMoveToCell == false) {
|
||||
failureCount++;
|
||||
}
|
||||
cellCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
unitImmediatelyBlocked = (failureCount == cellCount);
|
||||
return unitImmediatelyBlocked;
|
||||
}
|
||||
|
||||
void PathFinder::saveGame(XmlNode *rootNode) {
|
||||
std::map<string,string> mapTagReplacements;
|
||||
XmlNode *pathfinderNode = rootNode->addChild("PathFinder");
|
||||
|
|
|
@ -164,6 +164,8 @@ public:
|
|||
void removeUnitPrecache(Unit *unit);
|
||||
void clearCaches();
|
||||
|
||||
bool unitCannotMove(Unit *unit);
|
||||
|
||||
int findNodeIndex(Node *node, Nodes &nodeList);
|
||||
int findNodeIndex(Node *node, std::vector<Node> &nodeList);
|
||||
|
||||
|
|
|
@ -3672,9 +3672,17 @@ void Unit::setLastStuckFrameToCurrentFrame() {
|
|||
lastStuckFrame = getFrameCount();
|
||||
}
|
||||
|
||||
bool Unit::isLastStuckFrameWithinCurrentFrameTolerance() const {
|
||||
const int MIN_FRAME_ELAPSED_RETRY = 300;
|
||||
bool result (getFrameCount() - lastStuckFrame <= MIN_FRAME_ELAPSED_RETRY);
|
||||
bool Unit::isLastStuckFrameWithinCurrentFrameTolerance() {
|
||||
//const int MIN_FRAME_ELAPSED_RETRY = 300;
|
||||
const int MAX_BLOCKED_FRAME_THRESHOLD = 25000;
|
||||
int MIN_FRAME_ELAPSED_RETRY = 6;
|
||||
if(lastStuckFrame < MAX_BLOCKED_FRAME_THRESHOLD) {
|
||||
MIN_FRAME_ELAPSED_RETRY = random.randRange(2,6);
|
||||
}
|
||||
else {
|
||||
MIN_FRAME_ELAPSED_RETRY = random.randRange(6,8);
|
||||
}
|
||||
bool result (getFrameCount() - lastStuckFrame <= (MIN_FRAME_ELAPSED_RETRY * 100));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -722,7 +722,7 @@ public:
|
|||
std::string toString() const;
|
||||
bool needToUpdate();
|
||||
|
||||
bool isLastStuckFrameWithinCurrentFrameTolerance() const;
|
||||
bool isLastStuckFrameWithinCurrentFrameTolerance();
|
||||
inline uint32 getLastStuckFrame() const { return lastStuckFrame; }
|
||||
inline void setLastStuckFrame(uint32 value) { lastStuckFrame = value; }
|
||||
void setLastStuckFrameToCurrentFrame();
|
||||
|
|
|
@ -106,7 +106,9 @@ UnitUpdater::~UnitUpdater() {
|
|||
// ==================== progress skills ====================
|
||||
|
||||
//skill dependent actions
|
||||
void UnitUpdater::updateUnit(Unit *unit) {
|
||||
bool UnitUpdater::updateUnit(Unit *unit) {
|
||||
bool processUnitCommand = false;
|
||||
|
||||
Chrono chrono;
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||
|
||||
|
@ -153,6 +155,7 @@ void UnitUpdater::updateUnit(Unit *unit) {
|
|||
if(update == true) {
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
processUnitCommand = true;
|
||||
updateUnitCommand(unit,-1);
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after updateUnitCommand()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
@ -282,6 +285,8 @@ void UnitUpdater::updateUnit(Unit *unit) {
|
|||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
return processUnitCommand;
|
||||
}
|
||||
|
||||
// ==================== progress commands ====================
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
~UnitUpdater();
|
||||
|
||||
//update skills
|
||||
void updateUnit(Unit *unit);
|
||||
bool updateUnit(Unit *unit);
|
||||
|
||||
//update commands
|
||||
void updateUnitCommand(Unit *unit, int frameIndex);
|
||||
|
|
|
@ -462,6 +462,12 @@ void World::updateAllTilesetObjects() {
|
|||
}
|
||||
|
||||
void World::updateAllFactionUnits() {
|
||||
bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
|
||||
Chrono chronoPerf;
|
||||
if(showPerfStats) chronoPerf.start();
|
||||
char perfBuf[8096]="";
|
||||
std::vector<string> perfList;
|
||||
|
||||
scriptManager->onTimerTriggerEvent();
|
||||
|
||||
// Prioritize grouped command units so closest units to target go first
|
||||
|
@ -491,6 +497,11 @@ void World::updateAllFactionUnits() {
|
|||
faction->clearAproxCanMoveSoonCached();
|
||||
}
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
Chrono chrono;
|
||||
chrono.start();
|
||||
|
||||
|
@ -500,6 +511,12 @@ void World::updateAllFactionUnits() {
|
|||
bool slavesCompleted = masterController.waitTillSlavesTrigger(20000);
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d slavesCompleted = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount,slavesCompleted);
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// Signal the faction threads to do any pre-processing
|
||||
|
@ -508,6 +525,11 @@ void World::updateAllFactionUnits() {
|
|||
faction->signalWorkerThread(frameCount);
|
||||
}
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
bool workThreadsFinished = false;
|
||||
Chrono chrono;
|
||||
chrono.start();
|
||||
|
@ -527,14 +549,32 @@ void World::updateAllFactionUnits() {
|
|||
}
|
||||
}
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);
|
||||
}
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
//units
|
||||
Chrono chronoPerfUnit;
|
||||
int totalUnitsChecked = 0;
|
||||
int totalUnitsProcessed = 0;
|
||||
for(int i = 0; i < factionCount; ++i) {
|
||||
Faction *faction = getFaction(i);
|
||||
faction->clearUnitsPathfinding();
|
||||
|
||||
std::map<CommandClass,int> mapCommandCount;
|
||||
std::map<SkillClass,int> mapSkillCount;
|
||||
int unitCountStuck = 0;
|
||||
int unitCountUpdated = 0;
|
||||
|
||||
int unitCount = faction->getUnitCount();
|
||||
for(int j = 0; j < unitCount; ++j) {
|
||||
Unit *unit = faction->getUnit(j);
|
||||
|
@ -542,7 +582,70 @@ void World::updateAllFactionUnits() {
|
|||
throw megaglest_runtime_error("unit == NULL");
|
||||
}
|
||||
|
||||
unitUpdater.updateUnit(unit);
|
||||
CommandClass unitCommandClass = ccCount;
|
||||
if(unit->getCurrCommand() != NULL) {
|
||||
unitCommandClass = unit->getCurrCommand()->getCommandType()->getClass();
|
||||
}
|
||||
|
||||
SkillClass unitSkillClass = scCount;
|
||||
if(unit->getCurrSkill() != NULL) {
|
||||
unitSkillClass = unit->getCurrSkill()->getClass();
|
||||
}
|
||||
|
||||
if(showPerfStats) chronoPerfUnit.start();
|
||||
|
||||
int unitBlockCount = unit->getPath()->getBlockCount();
|
||||
bool isStuck = unit->getPath()->isStuck();
|
||||
bool isStuckWithinTolerance = unit->isLastStuckFrameWithinCurrentFrameTolerance();
|
||||
uint32 lastStuckFrame = unit->getLastStuckFrame();
|
||||
|
||||
if(unitUpdater.updateUnit(unit) == true) {
|
||||
unitCountUpdated++;
|
||||
|
||||
if(unit->getLastStuckFrame() == frameCount) {
|
||||
unitCountStuck++;
|
||||
}
|
||||
mapCommandCount[unitCommandClass] = mapCommandCount[unitCommandClass] + 1;
|
||||
mapSkillCount[unitSkillClass] = mapSkillCount[unitSkillClass] + 1;
|
||||
}
|
||||
totalUnitsChecked++;
|
||||
|
||||
if(showPerfStats && chronoPerfUnit.getMillis() >= 10) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " stuck: %d [%d] for unit:\n%sBEFORE unitBlockCount = %d, AFTER = %d, BEFORE lastStuckFrame = %u, AFTER: %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerfUnit.getMillis(),isStuck,isStuckWithinTolerance,unit->toString().c_str(),unitBlockCount,unit->getPath()->getBlockCount(),lastStuckFrame,unit->getLastStuckFrame());
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
}
|
||||
totalUnitsProcessed += unitCountUpdated;
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " faction: %d / %d unitCount = %d unitCountUpdated = %d unitCountStuck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis(),i+1,factionCount,unitCount,unitCountUpdated,unitCountStuck);
|
||||
perfList.push_back(perfBuf);
|
||||
|
||||
for(std::map<CommandClass,int>::iterator iterMap = mapCommandCount.begin();
|
||||
iterMap != mapCommandCount.end(); ++iterMap) {
|
||||
|
||||
sprintf(perfBuf,"Command class = %d, count = %d\n",iterMap->first,iterMap->second);
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
for(std::map<SkillClass,int>::iterator iterMap = mapSkillCount.begin();
|
||||
iterMap != mapSkillCount.end(); ++iterMap) {
|
||||
|
||||
sprintf(perfBuf,"Skill class = %d, count = %d\n",iterMap->first,iterMap->second);
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(showPerfStats) {
|
||||
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " totalUnitsProcessed = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis(),totalUnitsProcessed);
|
||||
perfList.push_back(perfBuf);
|
||||
}
|
||||
|
||||
if(showPerfStats && chronoPerf.getMillis() >= 50) {
|
||||
for(unsigned int x = 0; x < perfList.size(); ++x) {
|
||||
printf("%s",perfList[x].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue