- attempt to cleanup particles when a unit is deleted

This commit is contained in:
Mark Vejvoda
2010-09-06 17:52:33 +00:00
parent 58ab55a6aa
commit ca30612c9c
6 changed files with 120 additions and 49 deletions

View File

@@ -477,6 +477,14 @@ void Renderer::manageParticleSystem(ParticleSystem *particleSystem, ResourceScop
particleManager[rs]->manage(particleSystem); particleManager[rs]->manage(particleSystem);
} }
void Renderer::cleanupParticleSystems(vector<ParticleSystem *> &particleSystems, ResourceScope rs) {
particleManager[rs]->cleanupParticleSystems(particleSystems);
}
void Renderer::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems, ResourceScope rs) {
particleManager[rs]->cleanupUnitParticleSystems(particleSystems);
}
void Renderer::updateParticleManager(ResourceScope rs, int renderFps) { void Renderer::updateParticleManager(ResourceScope rs, int renderFps) {
particleManager[rs]->update(renderFps); particleManager[rs]->update(renderFps);
} }

View File

@@ -290,6 +290,8 @@ public:
Font2D *newFont(ResourceScope rs); Font2D *newFont(ResourceScope rs);
TextRenderer2D *getTextRenderer() const {return textRenderer;} TextRenderer2D *getTextRenderer() const {return textRenderer;}
void manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs); void manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs);
void cleanupParticleSystems(vector<ParticleSystem *> &particleSystems,ResourceScope rs);
void cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems,ResourceScope rs);
void updateParticleManager(ResourceScope rs,int renderFps=-1); void updateParticleManager(ResourceScope rs,int renderFps=-1);
void renderParticleManager(ResourceScope rs); void renderParticleManager(ResourceScope rs);
void swapBuffers(); void swapBuffers();

View File

@@ -200,7 +200,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
meetingPos= pos; meetingPos= pos;
alive= true; alive= true;
if (!type->hasSkillClass(scBeBuilt)) { if (type->hasSkillClass(scBeBuilt) == false) {
float rot= 0.f; float rot= 0.f;
random.init(id); random.init(id);
rot+= random.randRange(-5, 5); 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() // else it was set appropriately in setModelFacing()
if(getType()->getField(fAir)) currField=fAir; if(getType()->getField(fAir)) {
if(getType()->getField(fLand)) currField=fLand; currField = fAir;
}
if(getType()->getField(fLand)) {
currField = fLand;
}
fire= NULL; fire= NULL;
computeTotalUpgrade(); computeTotalUpgrade();
//starting skill //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__); 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__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//remove commands //remove commands
while(!commands.empty()){ while(commands.empty() == false) {
delete commands.back(); delete commands.back();
commands.pop_back(); commands.pop_back();
} }
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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 // fade(and by this remove) all unit particle systems
while(!unitParticleSystems.empty()){ while(unitParticleSystems.empty() == false) {
unitParticleSystems.back()->fade(); unitParticleSystems.back()->fade();
unitParticleSystems.pop_back(); unitParticleSystems.pop_back();
} }
@@ -420,11 +431,11 @@ bool Unit::isBeingBuilt() const{
throw runtime_error(szBuf); throw runtime_error(szBuf);
} }
return currSkill->getClass()==scBeBuilt; return (currSkill->getClass() == scBeBuilt);
} }
bool Unit::isBuilt() const{ bool Unit::isBuilt() const{
return !isBeingBuilt(); return (isBeingBuilt() == false);
} }
bool Unit::isPutrefacting() const{ bool Unit::isPutrefacting() const{
@@ -485,7 +496,7 @@ bool Unit::isInteresting(InterestingUnitType iut) const {
// ====================================== set ====================================== // ====================================== set ======================================
void Unit::setCurrSkill(const SkillType *currSkill){ void Unit::setCurrSkill(const SkillType *currSkill) {
if(currSkill == NULL) { if(currSkill == NULL) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); 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); throw runtime_error(szBuf);
} }
if(currSkill->getClass()!=this->currSkill->getClass()){ if(currSkill->getClass() != this->currSkill->getClass()) {
animProgress= 0; animProgress= 0;
lastAnimProgress= 0; lastAnimProgress= 0;
while(!unitParticleSystems.empty()){ while(unitParticleSystems.empty() == false) {
unitParticleSystems.back()->fade(); unitParticleSystems.back()->fade();
unitParticleSystems.pop_back(); unitParticleSystems.pop_back();
} }
} }
if(showUnitParticles && (!currSkill->unitParticleSystemTypes.empty()) && if(showUnitParticles && (currSkill->unitParticleSystemTypes.empty() == false) &&
(unitParticleSystems.empty()) ){ (unitParticleSystems.empty() == true) ) {
for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it!=currSkill->unitParticleSystemTypes.end(); ++it){ for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it != currSkill->unitParticleSystemTypes.end(); ++it) {
UnitParticleSystem *ups; UnitParticleSystem *ups = new UnitParticleSystem(200);
ups= new UnitParticleSystem(200);
(*it)->setValues(ups); (*it)->setValues(ups);
ups->setPos(getCurrVector()); ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmap()->getPixel3f(0,0)); ups->setFactionColor(getFaction()->getTexture()->getPixmap()->getPixel3f(0,0));
@@ -580,10 +590,10 @@ void Unit::setTargetPos(const Vec2i &targetPos){
void Unit::setVisible(const bool visible) { void Unit::setVisible(const bool visible) {
this->visible = 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); (*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); (*it)->setVisible(visible);
} }
} }
@@ -975,31 +985,31 @@ bool Unit::update(){
if (fire!=NULL) { if (fire!=NULL) {
fire->setPos(getCurrVector()); 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)->setPos(getCurrVector());
(*it)->setRotation(getRotation()); (*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)->setPos(getCurrVector());
(*it)->setRotation(getRotation()); (*it)->setRotation(getRotation());
} }
//checks //checks
if(animProgress>1.f){ if(animProgress>1.f) {
animProgress= currSkill->getClass()==scDie? 1.f: 0.f; animProgress= currSkill->getClass()==scDie? 1.f: 0.f;
} }
bool return_value = false; bool return_value = false;
//checks //checks
if(progress>=1.f){ if(progress>=1.f) {
lastRotation= targetRotation; lastRotation= targetRotation;
if(currSkill->getClass()!=scDie){ if(currSkill->getClass()!=scDie) {
progress= 0.f; progress= 0.f;
return_value = true; return_value = true;
} }
else{ else {
progress= 1.f; progress= 1.f;
deadCount++; deadCount++;
if(deadCount>=maxDeadCount){ if(deadCount>=maxDeadCount) {
toBeUndertaken= true; toBeUndertaken= true;
return_value = false; return_value = false;
} }
@@ -1483,14 +1493,14 @@ CommandResult Unit::undoCommand(Command *command){
void Unit::stopDamageParticles(){ void Unit::stopDamageParticles(){
// stop fire // stop fire
if(fire!=NULL) { if(fire != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
fire->fade(); fire->fade();
fire= NULL; fire = NULL;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
// stop additional particles // stop additional particles
while(!damageParticleSystems.empty()) { while(damageParticleSystems.empty() == false) {
damageParticleSystems.back()->fade(); damageParticleSystems.back()->fade();
damageParticleSystems.pop_back(); damageParticleSystems.pop_back();
} }
@@ -1521,8 +1531,10 @@ void Unit::startDamageParticles(){
fps->setTexture(CoreData::getInstance().getFireTexture()); fps->setTexture(CoreData::getInstance().getFireTexture());
fps->setParticleSize(type->getSize()/3.f); fps->setParticleSize(type->getSize()/3.f);
fire= fps; fire= fps;
fireParticleSystems.push_back(fps);
Renderer::getInstance().manageParticleSystem(fps, rsGame); Renderer::getInstance().manageParticleSystem(fps, rsGame);
if(showUnitParticles){ if(showUnitParticles) {
// smoke // smoke
UnitParticleSystem *ups= new UnitParticleSystem(400); UnitParticleSystem *ups= new UnitParticleSystem(400);
ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f));

View File

@@ -195,7 +195,7 @@ class Unit {
private: private:
typedef list<Command*> Commands; typedef list<Command*> Commands;
typedef list<UnitObserver*> Observers; typedef list<UnitObserver*> Observers;
typedef list<UnitParticleSystem*> UnitParticleSystems; typedef vector<UnitParticleSystem*> UnitParticleSystems;
public: public:
static const float speedDivider; static const float speedDivider;
@@ -254,8 +254,9 @@ private:
Commands commands; Commands commands;
Observers observers; Observers observers;
UnitParticleSystems unitParticleSystems; vector<UnitParticleSystem*> unitParticleSystems;
UnitParticleSystems damageParticleSystems; UnitParticleSystems damageParticleSystems;
vector<ParticleSystem*> fireParticleSystems;
CardinalDir modelFacing; CardinalDir modelFacing;

View File

@@ -423,9 +423,9 @@ public:
// class ParticleManager // class ParticleManager
// ===================================================== // =====================================================
class ParticleManager{ class ParticleManager {
private: private:
list<ParticleSystem*> particleSystems; vector<ParticleSystem *> particleSystems;
public: public:
~ParticleManager(); ~ParticleManager();
@@ -433,6 +433,10 @@ public:
void render(ParticleRenderer *pr, ModelRenderer *mr) const; void render(ParticleRenderer *pr, ModelRenderer *mr) const;
void manage(ParticleSystem *ps); void manage(ParticleSystem *ps);
void end(); void end();
void cleanupParticleSystems(ParticleSystem *ps);
void cleanupParticleSystems(vector<ParticleSystem *> &particleSystems);
void cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems);
int findParticleSystems(ParticleSystem *psFind, const vector<ParticleSystem *> &particleSystems) const;
}; };
}}//end namespace }}//end namespace

View File

@@ -905,11 +905,10 @@ ParticleManager::~ParticleManager(){
} }
void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{ void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{
list<ParticleSystem*>::const_iterator it; for (int i = 0; i < particleSystems.size(); i++) {
ParticleSystem *ps = particleSystems[i];
for (it=particleSystems.begin(); it!=particleSystems.end(); it++){ if(ps != NULL && ps->getVisible()) {
if((*it)->getVisible()){ ps->render(pr, mr);
(*it)->render(pr, mr);
} }
} }
} }
@@ -920,9 +919,10 @@ void ParticleManager::update(int renderFps) {
int particleSystemCount = particleSystems.size(); int particleSystemCount = particleSystems.size();
int particleCount = 0; int particleCount = 0;
list<ParticleSystem *>::iterator it;
for (it = particleSystems.begin(); it != particleSystems.end(); it++) { vector<ParticleSystem *> cleanupParticleSystemsList;
ParticleSystem *ps = *it; for (int i = 0; i < particleSystems.size(); i++) {
ParticleSystem *ps = particleSystems[i];
if(ps != NULL) { if(ps != NULL) {
particleCount += ps->getAliveParticleCount(); particleCount += ps->getAliveParticleCount();
@@ -934,25 +934,69 @@ void ParticleManager::update(int renderFps) {
if(showParticle == true) { if(showParticle == true) {
ps->update(); ps->update();
if(ps->isEmpty()) { if(ps->isEmpty()) {
delete ps; //delete ps;
*it= NULL; //*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); 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<ParticleSystem *> &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<ParticleSystem *> &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<UnitParticleSystem *> &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); particleSystems.push_back(ps);
} }
void ParticleManager::end(){ void ParticleManager::end() {
while(!particleSystems.empty()){ while(particleSystems.empty() == false) {
delete particleSystems.front(); delete particleSystems.back();
particleSystems.pop_front(); particleSystems.pop_back();
} }
} }