From ca30612c9c62a41f21769ad341ecb964f65383fc Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Mon, 6 Sep 2010 17:52:33 +0000 Subject: [PATCH] - attempt to cleanup particles when a unit is deleted --- source/glest_game/graphics/renderer.cpp | 8 ++ source/glest_game/graphics/renderer.h | 2 + source/glest_game/type_instances/unit.cpp | 70 ++++++++++------- source/glest_game/type_instances/unit.h | 5 +- source/shared_lib/include/graphics/particle.h | 8 +- .../shared_lib/sources/graphics/particle.cpp | 76 +++++++++++++++---- 6 files changed, 120 insertions(+), 49 deletions(-) diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index e0e2ab144..88be69e66 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -477,6 +477,14 @@ void Renderer::manageParticleSystem(ParticleSystem *particleSystem, ResourceScop particleManager[rs]->manage(particleSystem); } +void Renderer::cleanupParticleSystems(vector &particleSystems, ResourceScope rs) { + particleManager[rs]->cleanupParticleSystems(particleSystems); +} + +void Renderer::cleanupUnitParticleSystems(vector &particleSystems, ResourceScope rs) { + particleManager[rs]->cleanupUnitParticleSystems(particleSystems); +} + void Renderer::updateParticleManager(ResourceScope rs, int renderFps) { particleManager[rs]->update(renderFps); } diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 34a79525a..7000cacd5 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -290,6 +290,8 @@ public: Font2D *newFont(ResourceScope rs); TextRenderer2D *getTextRenderer() const {return textRenderer;} void manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs); + void cleanupParticleSystems(vector &particleSystems,ResourceScope rs); + void cleanupUnitParticleSystems(vector &particleSystems,ResourceScope rs); void updateParticleManager(ResourceScope rs,int renderFps=-1); void renderParticleManager(ResourceScope rs); void swapBuffers(); diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 584008564..a6f0c26d1 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -200,7 +200,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType meetingPos= pos; alive= true; - if (!type->hasSkillClass(scBeBuilt)) { + if (type->hasSkillClass(scBeBuilt) == false) { float rot= 0.f; random.init(id); rot+= random.randRange(-5, 5); @@ -210,15 +210,19 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType } // else it was set appropriately in setModelFacing() - if(getType()->getField(fAir)) currField=fAir; - if(getType()->getField(fLand)) currField=fLand; + if(getType()->getField(fAir)) { + currField = fAir; + } + if(getType()->getField(fLand)) { + currField = fLand; + } fire= NULL; computeTotalUpgrade(); //starting skill - this->currSkill=getType()->getFirstStOfClass(scStop); + this->currSkill = getType()->getFirstStOfClass(scStop); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -246,13 +250,20 @@ Unit::~Unit(){ } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //remove commands - while(!commands.empty()){ + while(commands.empty() == false) { delete commands.back(); commands.pop_back(); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + // If the unit is not visible we better make sure we cleanup associated particles + if(this->getVisible() == false) { + Renderer::getInstance().cleanupUnitParticleSystems(unitParticleSystems,rsGame); + Renderer::getInstance().cleanupParticleSystems(fireParticleSystems,rsGame); + } + // fade(and by this remove) all unit particle systems - while(!unitParticleSystems.empty()){ + while(unitParticleSystems.empty() == false) { unitParticleSystems.back()->fade(); unitParticleSystems.pop_back(); } @@ -420,11 +431,11 @@ bool Unit::isBeingBuilt() const{ throw runtime_error(szBuf); } - return currSkill->getClass()==scBeBuilt; + return (currSkill->getClass() == scBeBuilt); } bool Unit::isBuilt() const{ - return !isBeingBuilt(); + return (isBeingBuilt() == false); } bool Unit::isPutrefacting() const{ @@ -485,7 +496,7 @@ bool Unit::isInteresting(InterestingUnitType iut) const { // ====================================== set ====================================== -void Unit::setCurrSkill(const SkillType *currSkill){ +void Unit::setCurrSkill(const SkillType *currSkill) { if(currSkill == NULL) { char szBuf[4096]=""; sprintf(szBuf,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); @@ -497,20 +508,19 @@ void Unit::setCurrSkill(const SkillType *currSkill){ throw runtime_error(szBuf); } - if(currSkill->getClass()!=this->currSkill->getClass()){ + if(currSkill->getClass() != this->currSkill->getClass()) { animProgress= 0; lastAnimProgress= 0; - while(!unitParticleSystems.empty()){ + while(unitParticleSystems.empty() == false) { unitParticleSystems.back()->fade(); unitParticleSystems.pop_back(); } } - if(showUnitParticles && (!currSkill->unitParticleSystemTypes.empty()) && - (unitParticleSystems.empty()) ){ - for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it!=currSkill->unitParticleSystemTypes.end(); ++it){ - UnitParticleSystem *ups; - ups= new UnitParticleSystem(200); + if(showUnitParticles && (currSkill->unitParticleSystemTypes.empty() == false) && + (unitParticleSystems.empty() == true) ) { + for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it != currSkill->unitParticleSystemTypes.end(); ++it) { + UnitParticleSystem *ups = new UnitParticleSystem(200); (*it)->setValues(ups); ups->setPos(getCurrVector()); ups->setFactionColor(getFaction()->getTexture()->getPixmap()->getPixel3f(0,0)); @@ -580,10 +590,10 @@ void Unit::setTargetPos(const Vec2i &targetPos){ void Unit::setVisible(const bool visible) { this->visible = visible; - for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it!=unitParticleSystems.end(); ++it){ + for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { (*it)->setVisible(visible); } - for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it!=damageParticleSystems.end(); ++it){ + for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) { (*it)->setVisible(visible); } } @@ -975,31 +985,31 @@ bool Unit::update(){ if (fire!=NULL) { fire->setPos(getCurrVector()); } - for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it!=unitParticleSystems.end(); ++it){ + for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { (*it)->setPos(getCurrVector()); (*it)->setRotation(getRotation()); } - for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it!=damageParticleSystems.end(); ++it){ + for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) { (*it)->setPos(getCurrVector()); (*it)->setRotation(getRotation()); } //checks - if(animProgress>1.f){ + if(animProgress>1.f) { animProgress= currSkill->getClass()==scDie? 1.f: 0.f; } bool return_value = false; //checks - if(progress>=1.f){ + if(progress>=1.f) { lastRotation= targetRotation; - if(currSkill->getClass()!=scDie){ + if(currSkill->getClass()!=scDie) { progress= 0.f; return_value = true; } - else{ + else { progress= 1.f; deadCount++; - if(deadCount>=maxDeadCount){ + if(deadCount>=maxDeadCount) { toBeUndertaken= true; return_value = false; } @@ -1483,14 +1493,14 @@ CommandResult Unit::undoCommand(Command *command){ void Unit::stopDamageParticles(){ // stop fire - if(fire!=NULL) { + if(fire != NULL) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); fire->fade(); - fire= NULL; + fire = NULL; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } // stop additional particles - while(!damageParticleSystems.empty()) { + while(damageParticleSystems.empty() == false) { damageParticleSystems.back()->fade(); damageParticleSystems.pop_back(); } @@ -1521,8 +1531,10 @@ void Unit::startDamageParticles(){ fps->setTexture(CoreData::getInstance().getFireTexture()); fps->setParticleSize(type->getSize()/3.f); fire= fps; + fireParticleSystems.push_back(fps); + Renderer::getInstance().manageParticleSystem(fps, rsGame); - if(showUnitParticles){ + if(showUnitParticles) { // smoke UnitParticleSystem *ups= new UnitParticleSystem(400); ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 5d3a0af08..2c3947480 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -195,7 +195,7 @@ class Unit { private: typedef list Commands; typedef list Observers; - typedef list UnitParticleSystems; + typedef vector UnitParticleSystems; public: static const float speedDivider; @@ -254,8 +254,9 @@ private: Commands commands; Observers observers; - UnitParticleSystems unitParticleSystems; + vector unitParticleSystems; UnitParticleSystems damageParticleSystems; + vector fireParticleSystems; CardinalDir modelFacing; diff --git a/source/shared_lib/include/graphics/particle.h b/source/shared_lib/include/graphics/particle.h index 77a93ecf5..968724b00 100644 --- a/source/shared_lib/include/graphics/particle.h +++ b/source/shared_lib/include/graphics/particle.h @@ -423,9 +423,9 @@ public: // class ParticleManager // ===================================================== -class ParticleManager{ +class ParticleManager { private: - list particleSystems; + vector particleSystems; public: ~ParticleManager(); @@ -433,6 +433,10 @@ public: void render(ParticleRenderer *pr, ModelRenderer *mr) const; void manage(ParticleSystem *ps); void end(); + void cleanupParticleSystems(ParticleSystem *ps); + void cleanupParticleSystems(vector &particleSystems); + void cleanupUnitParticleSystems(vector &particleSystems); + int findParticleSystems(ParticleSystem *psFind, const vector &particleSystems) const; }; }}//end namespace diff --git a/source/shared_lib/sources/graphics/particle.cpp b/source/shared_lib/sources/graphics/particle.cpp index f5b069b90..4d1fe100c 100644 --- a/source/shared_lib/sources/graphics/particle.cpp +++ b/source/shared_lib/sources/graphics/particle.cpp @@ -905,11 +905,10 @@ ParticleManager::~ParticleManager(){ } void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{ - list::const_iterator it; - - for (it=particleSystems.begin(); it!=particleSystems.end(); it++){ - if((*it)->getVisible()){ - (*it)->render(pr, mr); + for (int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + if(ps != NULL && ps->getVisible()) { + ps->render(pr, mr); } } } @@ -920,9 +919,10 @@ void ParticleManager::update(int renderFps) { int particleSystemCount = particleSystems.size(); int particleCount = 0; - list::iterator it; - for (it = particleSystems.begin(); it != particleSystems.end(); it++) { - ParticleSystem *ps = *it; + + vector cleanupParticleSystemsList; + for (int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; if(ps != NULL) { particleCount += ps->getAliveParticleCount(); @@ -934,25 +934,69 @@ void ParticleManager::update(int renderFps) { if(showParticle == true) { ps->update(); if(ps->isEmpty()) { - delete ps; - *it= NULL; + //delete ps; + //*it= NULL; + cleanupParticleSystemsList.push_back(ps); } } } } - particleSystems.remove(NULL); + //particleSystems.remove(NULL); + cleanupParticleSystems(cleanupParticleSystemsList); if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, particleCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),particleSystemCount,particleCount); } -void ParticleManager::manage(ParticleSystem *ps){ +int ParticleManager::findParticleSystems(ParticleSystem *psFind, const vector &particleSystems) const { + int result = -1; + for (int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + if(ps != NULL && psFind != NULL && psFind == ps) { + result = i; + break; + } + } + return result; +} + +void ParticleManager::cleanupParticleSystems(ParticleSystem *ps) { + + int index = findParticleSystems(ps, this->particleSystems); + if(ps != NULL && index >= 0) { + delete ps; + this->particleSystems.erase(this->particleSystems.begin() + index); + } +} + +void ParticleManager::cleanupParticleSystems(vector &particleSystems) { + + for (int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + cleanupParticleSystems(ps); + } + + particleSystems.clear(); + //this->particleSystems.remove(NULL); +} + +void ParticleManager::cleanupUnitParticleSystems(vector &particleSystems) { + + for (int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + cleanupParticleSystems(ps); + } + particleSystems.clear(); + //this->particleSystems.remove(NULL); +} + +void ParticleManager::manage(ParticleSystem *ps) { particleSystems.push_back(ps); } -void ParticleManager::end(){ - while(!particleSystems.empty()){ - delete particleSystems.front(); - particleSystems.pop_front(); +void ParticleManager::end() { + while(particleSystems.empty() == false) { + delete particleSystems.back(); + particleSystems.pop_back(); } }