- updated code to protect against null pointers and uninitialized values and threading issues

This commit is contained in:
Mark Vejvoda 2013-02-05 00:01:40 +00:00
parent 196d1240f1
commit adc62b7df8
4 changed files with 338 additions and 303 deletions

View File

@ -598,6 +598,9 @@ void Unit::setModelFacing(CardinalDir value) {
// ====================================== get ======================================
Vec2i Unit::getCenteredPos() const {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId);
if(type == NULL) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str());
@ -608,6 +611,9 @@ Vec2i Unit::getCenteredPos() const {
}
Vec2f Unit::getFloatCenteredPos() const {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId);
if(type == NULL) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str());

View File

@ -95,6 +95,7 @@ UnitUpdater::~UnitUpdater() {
delete pathFinder;
pathFinder = NULL;
MutexSafeWrapper safeMutex(&mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
while(attackWarnings.empty() == false) {
AttackWarningData* awd=attackWarnings.back();
attackWarnings.pop_back();
@ -304,6 +305,7 @@ void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) {
bool commandUsesPathFinder = (frameIndex < 0);
if(frameIndex > 0) {
if(unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) {
commandUsesPathFinder = unit->getCurrCommand()->getCommandType()->usesPathfinder();
// Clear previous cached unit data
@ -311,9 +313,12 @@ void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) {
clearUnitPrecache(unit);
}
}
}
if(commandUsesPathFinder == true) {
if(unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) {
unit->getCurrCommand()->getCommandType()->update(this, unit, frameIndex);
}
}
if((minorDebugPerformance && frameIndex > 0) && (chrono.getMillis() - elapsed1) >= 1) {
//CommandClass cc = unit->getCurrCommand()->getCommandType()->commandTypeClass;
@ -379,7 +384,7 @@ void UnitUpdater::updateStop(Unit *unit, int frameIndex) {
//use it to attack
if(ast != NULL) {
if(attackableOnSight(unit, &sighted, ast)) {
if(attackableOnSight(unit, &sighted, ast, (frameIndex >= 0))) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(ct, sighted->getPos()));
break;
@ -393,7 +398,7 @@ void UnitUpdater::updateStop(Unit *unit, int frameIndex) {
else if(unit->getType()->hasCommandClass(ccMove)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(attackerOnSight(unit, &sighted)) {
if(attackerOnSight(unit, &sighted, (frameIndex >= 0))) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
Vec2i escapePos = unit->getPos() * 2 - sighted->getPos();
//SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -464,7 +469,13 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
Command *command= unit->getCurrCommand();
if(command == NULL) {
return;
}
const AttackCommandType *act= static_cast<const AttackCommandType*>(command->getCommandType());
if(act == NULL) {
return;
}
Unit *target= NULL;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -478,7 +489,9 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
}
//if found
if(attackableOnRange(unit, &target, act->getAttackSkillType())) {
//if(frameIndex < 0) {
{
if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) {
if(frameIndex < 0) {
if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(act->getAttackSkillType());
@ -496,7 +509,7 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
if(command->getUnit() != NULL) {
pos= command->getUnit()->getCenteredPos();
}
else if(attackableOnSight(unit, &target, act->getAttackSkillType())) {
else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) {
pos= target->getPos();
}
else {
@ -512,8 +525,12 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
TravelState tsValue = tsImpossible;
if(frameIndex < 0) {
//{
//printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
//fflush(stdout);
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
@ -521,6 +538,8 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
default:
throw megaglest_runtime_error("detected unsupported pathfinder type!");
}
//printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
//fflush(stdout);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -589,6 +608,7 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
}
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());
}
@ -623,7 +643,7 @@ void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) {
unit->setCurrSkill(asct->getAttackSkillType());
unit->setTarget(result.second);
}
else if(attackableOnRange(unit, &enemy, asct->getAttackSkillType())) {
else if(attackableOnRange(unit, &enemy, asct->getAttackSkillType(),(frameIndex >= 0))) {
unit->setCurrSkill(asct->getAttackSkillType());
unit->setTarget(enemy);
}
@ -699,7 +719,7 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) {
//std::pair<float,Vec2i> distance = map->getUnitDistanceToPos(unit,command->getPos(),command->getUnitType());
//unit->setCurrentUnitTitle("Distance: " + floatToStr(distance.first) + " build pos: " + distance.second.getString() + " current pos: " + unit->getPos().getString());
if(unit->getCurrSkill()->getClass() != scBuild) {
if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scBuild) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//if not building
@ -909,12 +929,14 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) {
//printf("In UpdateHarvest [%d - %s] unit->getCurrSkill()->getClass() = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrSkill()->getClass());
if(unit->getCurrSkill()->getClass() != scHarvest) {
if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scHarvest) {
//if not working
if(unit->getLoadCount() == 0) {
//if not loaded go for resources
Resource *r = map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource();
if(r != NULL && hct->canHarvest(r->getType())) {
SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(command->getPos()));
if(sc != NULL) {
Resource *r = sc->getResource();
if(r != NULL && hct != NULL && hct->canHarvest(r->getType())) {
//if can harvest dest. pos
bool canHarvestDestPos = false;
@ -1110,6 +1132,7 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) {
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
@ -2062,19 +2085,19 @@ bool UnitUpdater::searchForResource(Unit *unit, const HarvestCommandType *hct) {
return false;
}
bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr){
bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr, bool evalMode){
int range= unit->getType()->getSight();
return unitOnRange(unit, range, rangedPtr, NULL);
return unitOnRange(unit, range, rangedPtr, NULL,evalMode);
}
bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast){
bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast, bool evalMode) {
int range= unit->getType()->getSight();
return unitOnRange(unit, range, rangedPtr, ast);
return unitOnRange(unit, range, rangedPtr, ast, evalMode);
}
bool UnitUpdater::attackableOnRange(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast){
bool UnitUpdater::attackableOnRange(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast,bool evalMode) {
int range= ast->getTotalAttackRange(unit->getTotalUpgrade());
return unitOnRange(unit, range, rangedPtr, ast);
return unitOnRange(unit, range, rangedPtr, ast, evalMode);
}
bool UnitUpdater::findCachedCellsEnemies(Vec2i center, int range, int size, vector<Unit*> &enemies,
@ -2167,12 +2190,12 @@ void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange,
//if the unit has any enemy on range
bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
const AttackSkillType *ast) {
const AttackSkillType *ast,bool evalMode) {
vector<Unit*> enemies;
bool result=false;
//we check command target
const Unit *commandTarget = NULL;
if(unit->anyCommand()) {
if(unit->anyCommand() && unit->getCurrCommand() != NULL) {
commandTarget = static_cast<const Unit*>(unit->getCurrCommand()->getUnit());
}
if(commandTarget != NULL && commandTarget->isDead()) {
@ -2229,7 +2252,7 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
for(int i = 0; i< enemies.size(); ++i) {
Unit *enemy = enemies[i];
if(enemy->isAlive() == true) {
if(enemy != NULL && enemy->isAlive() == true) {
// Here we default to first enemy if no attackers found
if(enemySeen == NULL) {
*rangedPtr = enemy;
@ -2283,7 +2306,7 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
onlyEnemyUnits = false;
}
if(onlyEnemyUnits == false &&
if(evalMode == false && onlyEnemyUnits == false &&
enemyUnit->getTeam() != world->getThisTeamIndex()) {
Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos();
// find nearest Attack and cleanup old dates
@ -2291,6 +2314,7 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
float currentDistance = 0.f;
float nearestDistance = 0.f;
MutexSafeWrapper safeMutex(&mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
for(int i = attackWarnings.size() - 1; i >= 0; --i) {
if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again
AttackWarningData *toDelete =attackWarnings[i];
@ -2338,6 +2362,8 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
awd->lastFrameCount=world->getFrameCount();
awd->attackPosition.x=enemyFloatCenter.x;
awd->attackPosition.y=enemyFloatCenter.y;
MutexSafeWrapper safeMutex(&mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
attackWarnings.push_back(awd);
if(world->getAttackWarningsEnabled() == true) {
@ -2409,6 +2435,7 @@ vector<Unit*> UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillT
void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector<Unit*> &units) {
//all fields
if(cell != NULL) {
for(int k = 0; k < fieldCount; k++) {
Field f= static_cast<Field>(k);
@ -2420,6 +2447,7 @@ void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector<Unit*> &u
}
}
}
}
vector<Unit*> UnitUpdater::findUnitsInRange(const Unit *unit, int radius) {
int range = radius;

View File

@ -80,6 +80,7 @@ private:
PathFinder *pathFinder;
Game *game;
//RandomGen random;
Mutex mutexAttackWarnings;
float attackWarnRange;
AttackWarnings attackWarnings;
@ -143,10 +144,10 @@ private:
//misc
bool searchForResource(Unit *unit, const HarvestCommandType *hct);
bool attackerOnSight(Unit *unit, Unit **enemyPtr);
bool attackableOnSight(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast);
bool attackableOnRange(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast);
bool unitOnRange(Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast);
bool attackerOnSight(Unit *unit, Unit **enemyPtr, bool evalMode=false);
bool attackableOnSight(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode=false);
bool attackableOnRange(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode=false);
bool unitOnRange(Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast,bool evalMode=false);
void enemiesAtDistance(const Unit *unit, const Unit *priorityUnit, int distance, vector<Unit*> &enemies);
Unit * findPeerUnitBuilder(Unit *unit);

View File

@ -966,7 +966,7 @@ Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType
Unit *u= getFaction(factionIndex)->getUnit(i);
if(u != NULL) {
float tmpDist= u->getPos().dist(pos);
if(tmpDist < currDist && u->getType()->getStore(rt) > 0 && u->isOperative()) {
if(tmpDist < currDist && u->getType() != NULL && u->getType()->getStore(rt) > 0 && u->isOperative()) {
currDist= tmpDist;
currUnit= u;
}