- bugfixes related to attack-boost memory leaks

This commit is contained in:
Mark Vejvoda 2011-07-06 05:16:25 +00:00
parent 84870877ba
commit 15488ddb31
8 changed files with 172 additions and 74 deletions

View File

@ -31,9 +31,14 @@ namespace Glest{ namespace Game{
// =====================================================
// class ParticleSystemType
// =====================================================
const bool checkMemory = false;
static map<void *,int> memoryObjectList;
ParticleSystemType::ParticleSystemType() {
//printf("++ Create ParticleSystemType [%p]\n",this);
if(checkMemory) {
printf("++ Create ParticleSystemType [%p]\n",this);
memoryObjectList[this]++;
}
teamcolorNoEnergy=false;
teamcolorEnergy=false;
@ -47,7 +52,11 @@ ParticleSystemType::ParticleSystemType() {
}
ParticleSystemType::~ParticleSystemType() {
//printf("-- Delete ParticleSystemType [%p] type = [%s]\n",this,type.c_str());
if(checkMemory) {
printf("-- Delete ParticleSystemType [%p] type = [%s]\n",this,type.c_str());
memoryObjectList[this]--;
assert(memoryObjectList[this] == 0);
}
}
void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir,

View File

@ -3144,12 +3144,14 @@ void Renderer::renderSelectionEffects() {
for(unsigned int i = 0; i < effect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit
Unit *affectedUnit = effect.currentAttackBoostUnits[i];
int findUnitId = effect.currentAttackBoostUnits[i];
Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId);
if(affectedUnit != NULL) {
Vec3f currVecBoost = affectedUnit->getCurrVectorFlat();
currVecBoost.y += 0.3f;
Vec3f currVecBoost = affectedUnit->getCurrVectorFlat();
currVecBoost.y += 0.3f;
renderSelectionCircle(currVecBoost, affectedUnit->getType()->getSize(), 1.f);
renderSelectionCircle(currVecBoost, affectedUnit->getType()->getSize(), 1.f);
}
}
}
}

View File

@ -30,6 +30,10 @@ using Shared::Util::RandomGen;
namespace Glest { namespace Game {
CommandGroupSorter::CommandGroupSorter() {
this->unit = NULL;
}
CommandGroupSorter::CommandGroupSorter(Unit *unit) {
this->unit = unit;
}
@ -82,6 +86,7 @@ bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const {
FactionThread::FactionThread(Faction *faction) : BaseThread() {
this->faction = faction;
this->unitsInFactionsSorted = NULL;
}
void FactionThread::setQuitStatus(bool value) {
@ -194,6 +199,7 @@ void FactionThread::execute() {
world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first);
}
}
//this->unitsInFactionsSorted = NULL;
}
else {
int unitCount = faction->getUnitCount();

View File

@ -53,6 +53,7 @@ class CommandGroupSorter {
public:
Unit *unit;
CommandGroupSorter();
CommandGroupSorter(Unit *unit);
bool operator< (const CommandGroupSorter &j) const;
};

View File

@ -179,7 +179,16 @@ Unit *UnitReference::getUnit() const{
return NULL;
}
const bool checkMemory = false;
static map<void *,int> memoryObjectList;
UnitAttackBoostEffect::UnitAttackBoostEffect() {
if(checkMemory) {
printf("++ Create UnitAttackBoostEffect [%p] before count = %d\n",this,memoryObjectList[this]);
memoryObjectList[this]++;
printf("++ Create UnitAttackBoostEffect [%p] after count = %d\n",this,memoryObjectList[this]);
}
boost = NULL;
source = NULL;
ups = NULL;
@ -187,8 +196,14 @@ UnitAttackBoostEffect::UnitAttackBoostEffect() {
}
UnitAttackBoostEffect::~UnitAttackBoostEffect() {
if(checkMemory) {
printf("-- Delete UnitAttackBoostEffect [%p] count = %d\n",this,memoryObjectList[this]);
memoryObjectList[this]--;
assert(memoryObjectList[this] == 0);
}
if(ups != NULL) {
//ups->fade();
ups->fade();
vector<UnitParticleSystem *> particleSystemToRemove;
particleSystemToRemove.push_back(ups);
@ -235,6 +250,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
lastPathfindFailedFrame = 0;
lastPathfindFailedPos = Vec2i(0,0);
usePathfinderExtendedMaxNodes = false;
this->currentAttackBoostOriginatorEffect.skillType = NULL;
RandomGen random;
@ -368,6 +384,8 @@ Unit::~Unit() {
while(currentAttackBoostEffects.empty() == false) {
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
UnitAttackBoostEffect *ab = currentAttackBoostEffects.back();
delete ab;
currentAttackBoostEffects.pop_back();
}
@ -747,9 +765,9 @@ void Unit::setVisible(const bool visible) {
}
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if(effect.ups != NULL) {
effect.ups->setVisible(visible);
UnitAttackBoostEffect *effect = currentAttackBoostEffects[i];
if(effect != NULL && effect->ups != NULL) {
effect->ups->setVisible(visible);
}
}
if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
@ -1139,11 +1157,14 @@ void Unit::undertake() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->id, this->getFullName().c_str(),this->getDesc().c_str());
// Remove any units that were previously in attack-boost range
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0 && currentAttackBoostOriginatorEffect.skillType != NULL) {
for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId);
if(affectedUnit != NULL) {
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
}
//printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
@ -1351,10 +1372,10 @@ bool Unit::update() {
}
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if(effect.ups != NULL) {
effect.ups->setPos(getCurrVector());
effect.ups->setRotation(getRotation());
UnitAttackBoostEffect *effect = currentAttackBoostEffects[i];
if(effect != NULL && effect->ups != NULL) {
effect->ups->setPos(getCurrVector());
effect->ups->setRotation(getRotation());
}
}
if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
@ -1400,11 +1421,15 @@ bool Unit::update() {
}
// Remove any units that were previously in range
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0 && currentAttackBoostOriginatorEffect.skillType != NULL) {
for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId);
if(affectedUnit != NULL) {
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
}
//printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
@ -1423,7 +1448,7 @@ bool Unit::update() {
Unit *affectedUnit = candidates[i];
if(attackBoost->isAffected(this,affectedUnit) == true) {
if(affectedUnit->applyAttackBoost(attackBoost, this) == true) {
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit);
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit->getId());
//printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
@ -1461,12 +1486,12 @@ bool Unit::update() {
for(unsigned int i = 0; i < candidates.size(); ++i) {
Unit *affectedUnit = candidates[i];
std::vector<Unit *>::iterator iterFound = std::find(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(), currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), affectedUnit);
std::vector<int>::iterator iterFound = std::find(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(), currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), affectedUnit->getId());
if(attackBoost->isAffected(this,affectedUnit) == true) {
if(iterFound == currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) {
if(affectedUnit->applyAttackBoost(attackBoost, this) == true) {
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit);
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit->getId());
//printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
@ -1519,9 +1544,9 @@ bool Unit::update() {
bool Unit::unitHasAttackBoost(const AttackBoost *boost, const Unit *source) const {
bool result = false;
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
const UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if( effect.boost == boost &&
effect.source->getType()->getId() == source->getType()->getId()) {
const UnitAttackBoostEffect *effect = currentAttackBoostEffects[i];
if( effect != NULL && effect->boost == boost &&
effect->source->getType()->getId() == source->getType()->getId()) {
result = true;
break;
}
@ -1549,10 +1574,11 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) {
}
if(shouldApplyAttackBoost == true) {
currentAttackBoostEffects.push_back(UnitAttackBoostEffect());
UnitAttackBoostEffect &effect = currentAttackBoostEffects[currentAttackBoostEffects.size()-1];
effect.boost = boost;
effect.source = source;
//printf("APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
UnitAttackBoostEffect *effect = new UnitAttackBoostEffect();
effect->boost = boost;
effect->source = source;
bool wasAlive = alive;
int prevMaxHp = totalUpgrade.getMaxHp();
@ -1567,6 +1593,19 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) {
//printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp());
if(showUnitParticles == true) {
effect->upst = new UnitParticleSystemType();
*effect->upst = *boost->unitParticleSystemTypeForAffectedUnit;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
effect->ups = new UnitParticleSystem(200);
effect->upst->setValues(effect->ups);
effect->ups->setPos(getCurrVector());
effect->ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
Renderer::getInstance().manageParticleSystem(effect->ups, rsGame);
}
currentAttackBoostEffects.push_back(effect);
if(wasAlive == true) {
//startDamageParticles
startDamageParticles();
@ -1595,18 +1634,7 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) {
}
}
if(showUnitParticles == true) {
effect.upst = new UnitParticleSystemType();
*effect.upst = *boost->unitParticleSystemTypeForAffectedUnit;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
effect.ups = new UnitParticleSystem(200);
effect.upst->setValues(effect.ups);
effect.ups->setPos(getCurrVector());
effect.ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
Renderer::getInstance().manageParticleSystem(effect.ups, rsGame);
}
//currentAttackBoostEffects.push_back(effect);
//printf("APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
}
return shouldApplyAttackBoost;
}
@ -1618,7 +1646,7 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) {
throw runtime_error(szBuf);
}
//printf("DE-APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
//printf("DE-APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
bool wasAlive = alive;
int prevMaxHp = totalUpgrade.getMaxHp();
@ -1630,6 +1658,8 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) {
addItemToVault(&this->hp,this->hp);
if(wasAlive == true) {
//printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
//startDamageParticles
startDamageParticles();
@ -1657,14 +1687,18 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) {
}
}
//printf("DE-APPLYING ATTACK BOOST BEFORE END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if(effect.boost == boost && effect.source == source) {
UnitAttackBoostEffect *effect = currentAttackBoostEffects[i];
if(effect != NULL && effect->boost == boost && effect->source == source) {
delete effect;
currentAttackBoostEffects.erase(currentAttackBoostEffects.begin() + i);
break;
}
}
//printf("DE-APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
}
void Unit::tick() {

View File

@ -255,7 +255,7 @@ public:
~UnitAttackBoostEffectOriginator();
const SkillType *skillType;
std::vector<Unit *> currentAttackBoostUnits;
std::vector<int> currentAttackBoostUnits;
UnitAttackBoostEffect *currentAppliedEffect;
};
@ -373,7 +373,7 @@ private:
UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
std::vector<UnitAttackBoostEffect> currentAttackBoostEffects;
std::vector<UnitAttackBoostEffect *> currentAttackBoostEffects;
Mutex mutexCommands;

View File

@ -275,25 +275,29 @@ void World::updateAllFactionUnits() {
// Prioritize grouped command units so closest units to target go first
// units
const bool sortedUnitsAllowed = true;
int factionCount = getFactionCount();
std::map<int, std::vector<CommandGroupSorter> > unitsInFactionsSorted;
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
std::map<int, std::vector<CommandGroupSorter> > unitsInFactionsSorted;
if(sortedUnitsAllowed == true) {
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
unitsInFactionsSorted[faction->getIndex()].push_back(CommandGroupSorter(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");
}
unitsInFactionsSorted[faction->getIndex()].push_back(CommandGroupSorter(unit));
}
std::vector<CommandGroupSorter> &unitListToSort = unitsInFactionsSorted[faction->getIndex()];
std::sort(unitListToSort.begin(),unitListToSort.end());
}
std::vector<CommandGroupSorter> &unitListToSort = unitsInFactionsSorted[faction->getIndex()];
std::sort(unitListToSort.begin(),unitListToSort.end());
}
// Signal the faction threads to do any pre-processing
@ -302,8 +306,14 @@ void World::updateAllFactionUnits() {
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
std::vector<CommandGroupSorter> &unitListSorted = unitsInFactionsSorted[faction->getIndex()];
faction->signalWorkerThread(frameCount,&unitListSorted);
if(sortedUnitsAllowed == true) {
std::vector<CommandGroupSorter> &unitListSorted = unitsInFactionsSorted[faction->getIndex()];
faction->signalWorkerThread(frameCount,&unitListSorted);
}
else {
faction->signalWorkerThread(frameCount,NULL);
}
}
bool workThreadsFinished = false;
@ -340,11 +350,21 @@ void World::updateAllFactionUnits() {
throw runtime_error("faction == NULL");
}
std::vector<CommandGroupSorter> &unitListSorted = unitsInFactionsSorted[faction->getIndex()];
std::vector<CommandGroupSorter> *unitListSorted = NULL;
int unitCount = faction->getUnitCount();
if(sortedUnitsAllowed == true) {
unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
unitCount = unitListSorted->size();
}
int unitCount = unitListSorted.size();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = unitListSorted[j].unit;
Unit *unit = NULL;
if(sortedUnitsAllowed == true) {
unit = (*unitListSorted)[j].unit;
}
else {
unit = faction->getUnit(j);
}
if(unit == NULL) {
throw runtime_error("unit == NULL");
}

View File

@ -33,8 +33,14 @@ namespace Graphics {
// class ParticleSystem
// =====================================================
const bool checkMemory = false;
static map<void *,int> memoryObjectList;
ParticleSystem::ParticleSystem(int particleCount) {
//printf("++ Create ParticleSystem [%p]\n",this);
if(checkMemory) {
printf("++ Create ParticleSystem [%p]\n",this);
memoryObjectList[this]++;
}
//init particle vector
blendMode= bmOne;
@ -69,7 +75,11 @@ ParticleSystem::ParticleSystem(int particleCount) {
}
ParticleSystem::~ParticleSystem(){
//printf("-- Delete ParticleSystem [%p]\n",this);
if(checkMemory) {
printf("-- Delete ParticleSystem [%p]\n",this);
memoryObjectList[this]--;
assert(memoryObjectList[this] == 0);
}
//delete [] particles;
particles.clear();
@ -1084,10 +1094,17 @@ int ParticleManager::findParticleSystems(ParticleSystem *psFind, const vector<Pa
return result;
}
void ParticleManager::cleanupParticleSystems(ParticleSystem *ps){
void ParticleManager::cleanupParticleSystems(ParticleSystem *ps) {
int index= findParticleSystems(ps, this->particleSystems);
if(ps != NULL && index >= 0){
if(ps != NULL && index >= 0) {
// printf("-- Delete cleanupParticleSystems [%p]\n",ps);
// static map<void *,int> deleteList;
// if(deleteList.find(ps) != deleteList.end()) {
// assert(deleteList.find(ps) == deleteList.end());
// }
// deleteList[ps]++;
delete ps;
this->particleSystems.erase(this->particleSystems.begin() + index);
}
@ -1095,7 +1112,7 @@ void ParticleManager::cleanupParticleSystems(ParticleSystem *ps){
void ParticleManager::cleanupParticleSystems(vector<ParticleSystem *> &particleSystems){
for(unsigned int i= 0; i < particleSystems.size(); i++){
for(int i= particleSystems.size()-1; i >= 0; i--){
ParticleSystem *ps= particleSystems[i];
cleanupParticleSystems(ps);
}
@ -1106,7 +1123,7 @@ void ParticleManager::cleanupParticleSystems(vector<ParticleSystem *> &particleS
void ParticleManager::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems){
for(unsigned int i= 0; i < particleSystems.size(); i++){
for(int i= particleSystems.size()-1; i >= 0; i--){
ParticleSystem *ps= particleSystems[i];
cleanupParticleSystems(ps);
}
@ -1120,7 +1137,16 @@ void ParticleManager::manage(ParticleSystem *ps){
void ParticleManager::end(){
while(particleSystems.empty() == false){
delete particleSystems.back();
ParticleSystem *ps = particleSystems.back();
// printf("-- Delete end() [%p]\n",ps);
// static map<void *,int> deleteList;
// if(deleteList.find(ps) != deleteList.end()) {
// assert(deleteList.find(ps) == deleteList.end());
// }
// deleteList[ps]++;
delete ps;
particleSystems.pop_back();
}
}