- another attempt to fix command grouping bug (its now turned on be default again), please test for crashes or out of synch

This commit is contained in:
Mark Vejvoda 2011-09-22 20:42:06 +00:00
parent 7e16873efd
commit 72c12a3459
3 changed files with 48 additions and 201 deletions

View File

@ -30,41 +30,7 @@ using Shared::Util::RandomGen;
namespace Glest { namespace Game { namespace Glest { namespace Game {
CommandGroupSorter::CommandGroupSorter() { bool CommandGroupUnitSorter::compare(const Unit *l, const Unit *r) {
this->unit = NULL;
}
CommandGroupSorter::~CommandGroupSorter() {
this->unit = NULL;
}
CommandGroupSorter::CommandGroupSorter(Unit *unit) {
this->unit = unit;
}
CommandGroupSorter::CommandGroupSorter(const CommandGroupSorter &obj) {
copyAll(obj);
}
CommandGroupSorter::CommandGroupSorter(const CommandGroupSorter *obj) {
if(obj != NULL) {
copyAll(*obj);
}
}
CommandGroupSorter & CommandGroupSorter::operator=(const CommandGroupSorter &obj) {
copyAll(obj);
return *this;
}
void CommandGroupSorter::copyAll(const CommandGroupSorter &obj) {
if(this != &obj) {
this->unit = obj.unit;
}
}
bool CommandGroupSorter::comparePtr(const CommandGroupSorter *l, const CommandGroupSorter *r) {
if(!l) { if(!l) {
printf("Error l == NULL\n"); printf("Error l == NULL\n");
} }
@ -74,38 +40,32 @@ bool CommandGroupSorter::comparePtr(const CommandGroupSorter *l, const CommandGr
assert(l && r); assert(l && r);
if(l->unit == NULL || r->unit == NULL) if(l == NULL || r == NULL)
printf("Unit l [%s - %d] r [%s - %d]\n", printf("Unit l [%s - %d] r [%s - %d]\n",
(l->unit != NULL ? l->unit->getType()->getName().c_str() : "null"), (l != NULL ? l->getType()->getName().c_str() : "null"),
(l->unit != NULL ? l->unit->getId() : -1), (l != NULL ? l->getId() : -1),
(r->unit != NULL ? r->unit->getType()->getName().c_str() : "null"), (r != NULL ? r->getType()->getName().c_str() : "null"),
(r->unit != NULL ? r->unit->getId() : -1)); (r != NULL ? r->getId() : -1));
const CommandGroupSorter &lRef = *l;
const CommandGroupSorter &rRef = *r;
return (lRef < rRef);
}
bool CommandGroupSorter::compare(const CommandGroupSorter &l, const CommandGroupSorter &r) {
return (l < r);
}
bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const {
bool result = false; bool result = false;
// If comparer if null or dead // If comparer if null or dead
if(j.unit == NULL || j.unit->isAlive() == false) { if(r == NULL || r->isAlive() == false) {
// if source is null or dead also // if source is null or dead also
if((this->unit == NULL || this->unit->isAlive() == false)) { if((l == NULL || l->isAlive() == false)) {
return false; return false;
} }
return true; return true;
} }
else if((this->unit == NULL || this->unit->isAlive() == false)) { else if((l == NULL || l->isAlive() == false)) {
return false; return false;
} }
Command *command= this->unit->getCurrrentCommandThreadSafe(); // const Command *command= l->getCurrrentCommandThreadSafe();
Command *commandPeer = j.unit->getCurrrentCommandThreadSafe(); // const Command *commandPeer = r->getCurrrentCommandThreadSafe();
const Command *command= l->getCurrCommand();
const Command *commandPeer = r->getCurrCommand();
//Command *command= this->unit->getCurrCommand(); //Command *command= this->unit->getCurrCommand();
// Are we moving or attacking // Are we moving or attacking
@ -136,14 +96,14 @@ bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const {
result = curCommandGroupId < commandPeer->getUnitCommandGroupId(); result = curCommandGroupId < commandPeer->getUnitCommandGroupId();
} }
else { else {
float unitDist = this->unit->getCenteredPos().dist(command->getPos()); float unitDist = l->getCenteredPos().dist(command->getPos());
float unitDistPeer = j.unit->getCenteredPos().dist(commandPeer->getPos()); float unitDistPeer = r->getCenteredPos().dist(commandPeer->getPos());
// Closest unit in commandgroup // Closest unit in commandgroup
result = (unitDist < unitDistPeer); result = (unitDist < unitDistPeer);
} }
} }
else if(command == NULL && j.unit->getCurrrentCommandThreadSafe() != NULL) { else if(command == NULL && commandPeer != NULL) {
result = false; result = false;
} }
// else if(command == NULL && j.unit->getCurrrentCommandThreadSafe() == NULL) { // else if(command == NULL && j.unit->getCurrrentCommandThreadSafe() == NULL) {
@ -154,10 +114,10 @@ bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const {
if( commandPeer != NULL && if( commandPeer != NULL &&
(commandPeer->getCommandType()->getClass() != ccMove && (commandPeer->getCommandType()->getClass() != ccMove &&
commandPeer->getCommandType()->getClass() != ccAttack)) { commandPeer->getCommandType()->getClass() != ccAttack)) {
result = this->unit->getId() < j.unit->getId(); result = l->getId() < r->getId();
} }
else { else {
result = (this->unit->getId() < j.unit->getId()); result = (l->getId() < r->getId());
} }
} }
@ -166,13 +126,16 @@ bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const {
return result; return result;
} }
void Faction::sortUnitsByCommandGroups() {
std::sort(units.begin(),units.end(),CommandGroupUnitSorter::compare);
}
// ===================================================== // =====================================================
// class FactionThread // class FactionThread
// ===================================================== // =====================================================
FactionThread::FactionThread(Faction *faction) : BaseThread() { FactionThread::FactionThread(Faction *faction) : BaseThread() {
this->faction = faction; this->faction = faction;
this->unitsInFactionsSorted = NULL;
} }
void FactionThread::setQuitStatus(bool value) { void FactionThread::setQuitStatus(bool value) {
@ -180,20 +143,19 @@ void FactionThread::setQuitStatus(bool value) {
BaseThread::setQuitStatus(value); BaseThread::setQuitStatus(value);
if(value == true) { if(value == true) {
signalPathfinder(-1,NULL); signalPathfinder(-1);
} }
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
} }
void FactionThread::signalPathfinder(int frameIndex, std::vector<CommandGroupSorter *> *unitsInFactionsSorted) { void FactionThread::signalPathfinder(int frameIndex) {
if(frameIndex >= 0) { if(frameIndex >= 0) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
this->frameIndex.first = frameIndex; this->frameIndex.first = frameIndex;
this->frameIndex.second = false; this->frameIndex.second = false;
this->unitsInFactionsSorted = unitsInFactionsSorted;
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
} }
semTaskSignalled.signal(); semTaskSignalled.signal();
@ -205,7 +167,6 @@ void FactionThread::setTaskCompleted(int frameIndex) {
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
if(this->frameIndex.first == frameIndex) { if(this->frameIndex.first == frameIndex) {
this->frameIndex.second = true; this->frameIndex.second = true;
this->unitsInFactionsSorted = NULL;
} }
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
} }
@ -270,36 +231,17 @@ void FactionThread::execute() {
World *world = faction->getWorld(); World *world = faction->getWorld();
if(this->unitsInFactionsSorted != NULL) { int unitCount = faction->getUnitCount();
//std::vector<CommandGroupSorter> *unitsInFactionsSorted for(int j = 0; j < unitCount; ++j) {
int unitCount = unitsInFactionsSorted->size(); Unit *unit = faction->getUnit(j);
for(int j = 0; j < unitCount; ++j) { if(unit == NULL) {
Unit *unit = (*unitsInFactionsSorted)[j]->unit; throw runtime_error("unit == NULL");
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
bool update = unit->needToUpdate();
//update = true;
if(update == true) {
world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first);
}
} }
//this->unitsInFactionsSorted = NULL;
}
else {
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
bool update = unit->needToUpdate(); bool update = unit->needToUpdate();
//update = true; //update = true;
if(update == true) { if(update == true) {
world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first); world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first);
}
} }
} }
@ -371,9 +313,9 @@ Faction::~Faction() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
void Faction::signalWorkerThread(int frameIndex, std::vector<CommandGroupSorter *> *unitsInFactionsSorted) { void Faction::signalWorkerThread(int frameIndex) {
if(workerThread != NULL) { if(workerThread != NULL) {
workerThread->signalPathfinder(frameIndex,unitsInFactionsSorted); workerThread->signalPathfinder(frameIndex);
} }
} }

View File

@ -49,22 +49,9 @@ class Faction;
/// Each of the game players /// Each of the game players
// ===================================================== // =====================================================
class CommandGroupSorter { class CommandGroupUnitSorter {
public: public:
Unit *unit; static bool compare(const Unit *l, const Unit *r);
CommandGroupSorter();
~CommandGroupSorter();
CommandGroupSorter(Unit *unit);
CommandGroupSorter(const CommandGroupSorter &obj);
CommandGroupSorter(const CommandGroupSorter *obj);
CommandGroupSorter & operator=(const CommandGroupSorter &obj);
bool operator< (const CommandGroupSorter &j) const;
static bool comparePtr(const CommandGroupSorter *l, const CommandGroupSorter *r);
static bool compare(const CommandGroupSorter &l, const CommandGroupSorter &r);
protected:
void copyAll(const CommandGroupSorter &obj);
}; };
class FactionThread : public BaseThread { class FactionThread : public BaseThread {
@ -74,7 +61,6 @@ protected:
Semaphore semTaskSignalled; Semaphore semTaskSignalled;
Mutex triggerIdMutex; Mutex triggerIdMutex;
std::pair<int,bool> frameIndex; std::pair<int,bool> frameIndex;
std::vector<CommandGroupSorter *> *unitsInFactionsSorted;
virtual void setQuitStatus(bool value); virtual void setQuitStatus(bool value);
virtual void setTaskCompleted(int frameIndex); virtual void setTaskCompleted(int frameIndex);
@ -83,7 +69,7 @@ protected:
public: public:
FactionThread(Faction *faction); FactionThread(Faction *faction);
virtual void execute(); virtual void execute();
void signalPathfinder(int frameIndex,std::vector<CommandGroupSorter *> *unitsInFactionsSorted); void signalPathfinder(int frameIndex);
bool isSignalPathfinderCompleted(int frameIndex); bool isSignalPathfinderCompleted(int frameIndex);
}; };
@ -234,10 +220,12 @@ public:
World * getWorld() { return world; } World * getWorld() { return world; }
int getFrameCount(); int getFrameCount();
void signalWorkerThread(int frameIndex,std::vector<CommandGroupSorter *> *unitsInFactionsSorted); void signalWorkerThread(int frameIndex);
bool isWorkerThreadSignalCompleted(int frameIndex); bool isWorkerThreadSignalCompleted(int frameIndex);
void limitResourcesToStore(); void limitResourcesToStore();
void sortUnitsByCommandGroups();
std::string toString() const; std::string toString() const;
private: private:

View File

@ -281,8 +281,7 @@ void World::updateAllFactionUnits() {
// Prioritize grouped command units so closest units to target go first // Prioritize grouped command units so closest units to target go first
// units // units
Config &config= Config::getInstance(); Config &config= Config::getInstance();
bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","false"); bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true");
std::map<int, std::vector<CommandGroupSorter *> > unitsInFactionsSorted;
int factionCount = getFactionCount(); int factionCount = getFactionCount();
if(sortedUnitsAllowed == true) { if(sortedUnitsAllowed == true) {
@ -292,52 +291,18 @@ void World::updateAllFactionUnits() {
throw runtime_error("faction == NULL"); throw runtime_error("faction == NULL");
} }
std::vector<CommandGroupSorter *> &unitListToSort = unitsInFactionsSorted[faction->getIndex()]; // Sort units by command groups
unitListToSort.clear(); faction->sortUnitsByCommandGroups();
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
unitListToSort.push_back(new CommandGroupSorter(unit));
}
if(unitListToSort.empty() == false) {
//printf("About to Sort...\n");
std::sort(unitListToSort.begin(),unitListToSort.end(),CommandGroupSorter::comparePtr);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
for(unsigned int x = 0; x < unitListToSort.size(); ++x) {
CommandGroupSorter *sorter = unitListToSort[x];
sprintf(szBuf,"List %d / %ld unit [%d - %s] cmd [%s]",x,unitListToSort.size(),sorter->unit->getId(),sorter->unit->getFullName().c_str(),(sorter->unit->getCurrCommand() == NULL ? "NULL" : sorter->unit->getCurrCommand()->toString().c_str()));
sorter->unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
} }
} }
//sortedUnitsAllowed = false;
// Signal the faction threads to do any pre-processing // Signal the faction threads to do any pre-processing
for(int i = 0; i < factionCount; ++i) { for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i); Faction *faction = getFaction(i);
if(faction == NULL) { if(faction == NULL) {
throw runtime_error("faction == NULL"); throw runtime_error("faction == NULL");
} }
faction->signalWorkerThread(frameCount);
if(sortedUnitsAllowed == true) {
std::vector<CommandGroupSorter *> *unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
faction->signalWorkerThread(frameCount,unitListSorted);
}
else {
faction->signalWorkerThread(frameCount,NULL);
}
} }
bool workThreadsFinished = false; bool workThreadsFinished = false;
@ -374,63 +339,15 @@ void World::updateAllFactionUnits() {
throw runtime_error("faction == NULL"); throw runtime_error("faction == NULL");
} }
std::vector<CommandGroupSorter *> *unitListSorted = NULL;
int unitCount = faction->getUnitCount(); int unitCount = faction->getUnitCount();
if(sortedUnitsAllowed == true) {
unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
unitCount = unitListSorted->size();
}
for(int j = 0; j < unitCount; ++j) { for(int j = 0; j < unitCount; ++j) {
Unit *unit = NULL; Unit *unit = faction->getUnit(j);
if(sortedUnitsAllowed == true) {
unit = (*unitListSorted)[j]->unit;
}
else {
unit = faction->getUnit(j);
}
if(unit == NULL) { if(unit == NULL) {
throw runtime_error("unit == NULL"); throw runtime_error("unit == NULL");
} }
unitUpdater.updateUnit(unit); unitUpdater.updateUnit(unit);
} }
// int unitCount = faction->getUnitCount();
// for(int j = 0; j < unitCount; ++j) {
// Unit *unit = faction->getUnit(j);
// if(unit == NULL) {
// throw runtime_error("unit == NULL");
// }
//
// unitUpdater.updateUnit(unit);
// }
}
if(sortedUnitsAllowed == true) {
if(workThreadsFinished == false) {
sleep(0);
}
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
std::vector<CommandGroupSorter *> *unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
unsigned int unitCount = unitListSorted->size();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = (*unitListSorted)[j]->unit;
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
delete (*unitListSorted)[j];
(*unitListSorted)[j] = NULL;
}
}
unitsInFactionsSorted.clear();
} }
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount); if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);