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

View File

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

View File

@ -281,8 +281,7 @@ void World::updateAllFactionUnits() {
// Prioritize grouped command units so closest units to target go first
// units
Config &config= Config::getInstance();
bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","false");
std::map<int, std::vector<CommandGroupSorter *> > unitsInFactionsSorted;
bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true");
int factionCount = getFactionCount();
if(sortedUnitsAllowed == true) {
@ -292,52 +291,18 @@ void World::updateAllFactionUnits() {
throw runtime_error("faction == NULL");
}
std::vector<CommandGroupSorter *> &unitListToSort = unitsInFactionsSorted[faction->getIndex()];
unitListToSort.clear();
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);
}
}
// Sort units by command groups
faction->sortUnitsByCommandGroups();
}
}
//sortedUnitsAllowed = false;
// Signal the faction threads to do any pre-processing
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
if(sortedUnitsAllowed == true) {
std::vector<CommandGroupSorter *> *unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
faction->signalWorkerThread(frameCount,unitListSorted);
}
else {
faction->signalWorkerThread(frameCount,NULL);
}
faction->signalWorkerThread(frameCount);
}
bool workThreadsFinished = false;
@ -374,63 +339,15 @@ void World::updateAllFactionUnits() {
throw runtime_error("faction == NULL");
}
std::vector<CommandGroupSorter *> *unitListSorted = NULL;
int unitCount = faction->getUnitCount();
if(sortedUnitsAllowed == true) {
unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
unitCount = unitListSorted->size();
}
for(int j = 0; j < unitCount; ++j) {
Unit *unit = NULL;
if(sortedUnitsAllowed == true) {
unit = (*unitListSorted)[j]->unit;
}
else {
unit = faction->getUnit(j);
}
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
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);