diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-04-07 11:27:29 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-05-08 14:03:04 +0000 |
commit | 928c1584b67cb93a2c1e180a73574a84b4e7af01 (patch) | |
tree | f1619940e83fb21871a1fd6993c78a2d092759e0 | |
parent | 13a0a505bde8868e7ac9d50aa7dfe7d6bbae60c4 (diff) | |
download | mana-particle-system.tar.gz mana-particle-system.tar.bz2 mana-particle-system.tar.xz mana-particle-system.zip |
ParticleEmitter cleanupsparticle-system
* Don't needlessly use explicit heap allocation for ParticleEmitter
instances.
* Initialize ParticleEmitter members at the definition.
-rw-r--r-- | src/particle.cpp | 25 | ||||
-rw-r--r-- | src/particle.h | 15 | ||||
-rw-r--r-- | src/particleemitter.cpp | 59 | ||||
-rw-r--r-- | src/particleemitter.h | 22 | ||||
-rw-r--r-- | src/particleemitterprop.h | 13 |
5 files changed, 54 insertions, 80 deletions
diff --git a/src/particle.cpp b/src/particle.cpp index 0cd680e8..977e11de 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -177,7 +177,7 @@ bool Particle::update() { for (auto &childEmitter : mChildEmitters) { - Particles newParticles = childEmitter->createParticles(mLifetimePast); + Particles newParticles = childEmitter.createParticles(mLifetimePast); for (auto &newParticle : newParticles) { newParticle->moveBy(mPos); @@ -324,34 +324,32 @@ Particle *Particle::addEffect(const std::string &particleEffectFile, { if (emitterNode.name() == "emitter") { - ParticleEmitter *newEmitter; - newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap, - rotation, dyePalettes); - newParticle->addEmitter(newEmitter); + newParticle->addEmitter(ParticleEmitter(emitterNode, newParticle, mMap, + rotation, dyePalettes)); } else if (emitterNode.name() == "deatheffect") { std::string deathEffect { emitterNode.textContent() }; - char deathEffectConditions = 0x00; + unsigned char deathEffectConditions = 0x00; if (emitterNode.getBoolProperty("on-floor", true)) { - deathEffectConditions += Particle::DEAD_FLOOR; + deathEffectConditions |= Particle::DEAD_FLOOR; } if (emitterNode.getBoolProperty("on-sky", true)) { - deathEffectConditions += Particle::DEAD_SKY; + deathEffectConditions |= Particle::DEAD_SKY; } if (emitterNode.getBoolProperty("on-other", false)) { - deathEffectConditions += Particle::DEAD_OTHER; + deathEffectConditions |= Particle::DEAD_OTHER; } if (emitterNode.getBoolProperty("on-impact", true)) { - deathEffectConditions += Particle::DEAD_IMPACT; + deathEffectConditions |= Particle::DEAD_IMPACT; } if (emitterNode.getBoolProperty("on-timeout", true)) { - deathEffectConditions += Particle::DEAD_TIMEOUT; + deathEffectConditions |= Particle::DEAD_TIMEOUT; } newParticle->setDeathEffect(deathEffect, deathEffectConditions); } @@ -408,7 +406,7 @@ void Particle::adjustEmitterSize(int w, int h) return; for (auto &childEmitter : mChildEmitters) - childEmitter->adjustSize(w, h); + childEmitter.adjustSize(w, h); } float Particle::getCurrentAlpha() const @@ -426,9 +424,6 @@ float Particle::getCurrentAlpha() const void Particle::clear() { - delete_all(mChildEmitters); - mChildEmitters.clear(); - delete_all(mChildParticles); mChildParticles.clear(); } diff --git a/src/particle.h b/src/particle.h index 96013b71..aac45e09 100644 --- a/src/particle.h +++ b/src/particle.h @@ -23,6 +23,7 @@ #include "actor.h" #include "guichanfwd.h" +#include "particleemitter.h" #include "vector.h" #include <list> @@ -33,7 +34,6 @@ class Particle; class ParticleEmitter; using Particles = std::list<Particle *>; -using Emitters = std::list<ParticleEmitter *>; /** * A particle spawned by a ParticleEmitter. @@ -41,7 +41,7 @@ using Emitters = std::list<ParticleEmitter *>; class Particle : public Actor { public: - enum AliveStatus + enum AliveStatus : unsigned char { ALIVE = 0, DEAD_TIMEOUT = 1, @@ -119,9 +119,12 @@ class Particle : public Actor /** * Adds an emitter to the particle. */ - void addEmitter(ParticleEmitter *emitter) + void addEmitter(const ParticleEmitter &emitter) { mChildEmitters.push_back(emitter); } + void addEmitter(ParticleEmitter &&emitter) + { mChildEmitters.push_back(std::move(emitter)); } + /** * Sets the position in 3 dimensional space in pixels relative to map. */ @@ -246,7 +249,7 @@ class Particle : public Actor void setAlpha(float alpha) override {} - void setDeathEffect(const std::string &effectFile, char conditions) + void setDeathEffect(const std::string &effectFile, unsigned char conditions) { mDeathEffect = effectFile; mDeathEffectConditions = conditions; } protected: @@ -266,11 +269,11 @@ class Particle : public Actor AliveStatus mAlive = ALIVE; /**< Is the particle supposed to be drawn and updated?*/ // generic properties bool mAutoDelete = true; /**< May the particle request its deletion by the parent particle? */ - Emitters mChildEmitters; /**< List of child emitters. */ + std::list<ParticleEmitter> mChildEmitters; /**< List of child emitters. */ Particles mChildParticles; /**< List of particles controlled by this particle */ bool mAllowSizeAdjust = false; /**< Can the effect size be adjusted by the object props in the map file? */ std::string mDeathEffect; /**< Particle effect file to be spawned when the particle dies */ - char mDeathEffectConditions = 0;/**< Bitfield of death conditions which trigger spawning of the death particle */ + unsigned char mDeathEffectConditions = 0; /**< Bitfield of death conditions which trigger spawning of the death particle */ // dynamic particle float mGravity = 0.0f; /**< Downward acceleration in pixels per game-tick. */ diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp index 525c5a60..e3c052fd 100644 --- a/src/particleemitter.cpp +++ b/src/particleemitter.cpp @@ -43,27 +43,6 @@ ParticleEmitter::ParticleEmitter(XML::Node emitterNode, Particle *target, mMap = map; mParticleTarget = target; - // Initializing default values - mParticlePosX.set(0.0f); - mParticlePosY.set(0.0f); - mParticlePosZ.set(0.0f); - mParticleAngleHorizontal.set(0.0f); - mParticleAngleVertical.set(0.0f); - mParticlePower.set(0.0f); - mParticleGravity.set(0.0f); - mParticleRandomness.set(0); - mParticleBounce.set(0.0f); - mParticleFollow = false; - mParticleAcceleration.set(0.0f); - mParticleDieDistance.set(-1.0f); - mParticleMomentum.set(1.0f); - mParticleLifetime.set(-1); - mParticleFadeOut.set(0); - mParticleFadeIn.set(0); - mOutput.set(1); - mOutputPause.set(0); - mParticleAlpha.set(1.0f); - for (auto propertyNode : emitterNode.children()) { if (propertyNode.name() == "property") @@ -76,7 +55,6 @@ ParticleEmitter::ParticleEmitter(XML::Node emitterNode, Particle *target, } else if (name == "position-y") { - mParticlePosY = readParticleEmitterProp(propertyNode, 0.0f); mParticlePosY.minVal *= SIN45; mParticlePosY.maxVal *= SIN45; @@ -92,7 +70,6 @@ ParticleEmitter::ParticleEmitter(XML::Node emitterNode, Particle *target, else if (name == "image") { std::string image = propertyNode.getProperty("value", ""); - // Don't leak when multiple images are defined if (!image.empty() && !mParticleImage) { if (!dyePalettes.empty()) @@ -188,7 +165,7 @@ ParticleEmitter::ParticleEmitter(XML::Node emitterNode, Particle *target, { ParticleEmitter newEmitter(propertyNode, mParticleTarget, map, rotation, dyePalettes); - mParticleChildEmitters.push_back(newEmitter); + mParticleChildEmitters.push_back(std::move(newEmitter)); } else if (propertyNode.name() == "rotation") { @@ -201,26 +178,26 @@ ParticleEmitter::ParticleEmitter(XML::Node emitterNode, Particle *target, else if (propertyNode.name() == "deatheffect") { mDeathEffect = propertyNode.textContent(); - mDeathEffectConditions = 0x00; + if (propertyNode.getBoolProperty("on-floor", true)) { - mDeathEffectConditions += Particle::DEAD_FLOOR; + mDeathEffectConditions |= Particle::DEAD_FLOOR; } if (propertyNode.getBoolProperty("on-sky", true)) { - mDeathEffectConditions += Particle::DEAD_SKY; + mDeathEffectConditions |= Particle::DEAD_SKY; } if (propertyNode.getBoolProperty("on-other", false)) { - mDeathEffectConditions += Particle::DEAD_OTHER; + mDeathEffectConditions |= Particle::DEAD_OTHER; } if (propertyNode.getBoolProperty("on-impact", true)) { - mDeathEffectConditions += Particle::DEAD_IMPACT; + mDeathEffectConditions |= Particle::DEAD_IMPACT; } if (propertyNode.getBoolProperty("on-timeout", true)) { - mDeathEffectConditions += Particle::DEAD_TIMEOUT; + mDeathEffectConditions |= Particle::DEAD_TIMEOUT; } } } @@ -271,11 +248,11 @@ ParticleEmitter::~ParticleEmitter() = default; template <typename T> ParticleEmitterProp<T> ParticleEmitter::readParticleEmitterProp(XML::Node propertyNode, T def) { - ParticleEmitterProp<T> retval; + def = propertyNode.getFloatProperty("value", (double) def); + const T min = (T) propertyNode.getFloatProperty("min", (double) def); + const T max = (T) propertyNode.getFloatProperty("max", (double) def); - def = (T) propertyNode.getFloatProperty("value", (double) def); - retval.set((T) propertyNode.getFloatProperty("min", (double) def), - (T) propertyNode.getFloatProperty("max", (double) def)); + ParticleEmitterProp<T> retval(min, max); std::string change = propertyNode.getProperty("change-func", "none"); T amplitude = (T) propertyNode.getFloatProperty("change-amplitude", 0.0); @@ -360,14 +337,10 @@ std::list<Particle *> ParticleEmitter::createParticles(int tick) newParticle->setAlpha(mParticleAlpha.value(tick)); for (auto &particleChildEmitter : mParticleChildEmitters) - { - newParticle->addEmitter(new ParticleEmitter(particleChildEmitter)); - } + newParticle->addEmitter(particleChildEmitter); if (!mDeathEffect.empty()) - { newParticle->setDeathEffect(mDeathEffect, mDeathEffectConditions); - } newParticles.push_back(newParticle); } @@ -383,19 +356,17 @@ void ParticleEmitter::adjustSize(int w, int h) int oldWidth = mParticlePosX.maxVal - mParticlePosX.minVal; int oldHeight = mParticlePosX.maxVal - mParticlePosY.minVal; int oldArea = oldWidth * oldHeight; + + // when the effect has no dimension it is not designed to be resizeable if (oldArea == 0) - { - //when the effect has no dimension it is - //not designed to be resizeable return; - } // set the new dimensions mParticlePosX.set(0, w); mParticlePosY.set(0, h); int newArea = w * h; // adjust the output so that the particle density stays the same - float outputFactor = (float)newArea / (float)oldArea; + float outputFactor = (float) newArea / oldArea; mOutput.minVal *= outputFactor; mOutput.maxVal *= outputFactor; } diff --git a/src/particleemitter.h b/src/particleemitter.h index ede5a71d..fdbf2d1a 100644 --- a/src/particleemitter.h +++ b/src/particleemitter.h @@ -41,9 +41,11 @@ class Particle; class ParticleEmitter { public: - ParticleEmitter(XML::Node emitterNode, Particle *target, Map *map, + ParticleEmitter(XML::Node emitterNode, + Particle *target, + Map *map, int rotation = 0, - const std::string& dyePalettes = std::string()); + const std::string &dyePalettes = std::string()); /** * Copy Constructor (necessary for reference counting of particle images) @@ -99,27 +101,27 @@ class ParticleEmitter ParticleEmitterProp<float> mParticleGravity; ParticleEmitterProp<int> mParticleRandomness; ParticleEmitterProp<float> mParticleBounce; - bool mParticleFollow; + bool mParticleFollow = false; /* * Properties of targeting particles: */ Particle *mParticleTarget; ParticleEmitterProp<float> mParticleAcceleration; - ParticleEmitterProp<float> mParticleDieDistance; - ParticleEmitterProp<float> mParticleMomentum; + ParticleEmitterProp<float> mParticleDieDistance { -1.0f }; + ParticleEmitterProp<float> mParticleMomentum { 1.0f }; /* * Behavior over time of the particles: */ - ParticleEmitterProp<int> mParticleLifetime; + ParticleEmitterProp<int> mParticleLifetime { -1 }; ParticleEmitterProp<int> mParticleFadeOut; ParticleEmitterProp<int> mParticleFadeIn; Map *mMap; /**< Map the particles are spawned on */ - ParticleEmitterProp<int> mOutput; /**< Number of particles spawned per update */ - ParticleEmitterProp<int> mOutputPause; /**< Pause in frames between two spawns */ + ParticleEmitterProp<int> mOutput { 1 }; /**< Number of particles spawned per update */ + ParticleEmitterProp<int> mOutputPause; /**< Pause in frames between two spawns */ int mOutputPauseLeft = 0; /* @@ -128,13 +130,13 @@ class ParticleEmitter ResourceRef<Image> mParticleImage; /**< Particle image, if used */ Animation mParticleAnimation; /**< Filename of particle animation file */ Animation mParticleRotation; /**< Filename of particle rotation file */ - ParticleEmitterProp<float> mParticleAlpha; /**< Opacity of the graphical representation of the particles */ + ParticleEmitterProp<float> mParticleAlpha { 1.0f }; /**< Opacity of the graphical representation of the particles */ /* * Death effect of the particles */ std::string mDeathEffect; - char mDeathEffectConditions; + unsigned char mDeathEffectConditions = 0x00; /** List of emitters the spawned particles are equipped with */ std::list<ParticleEmitter> mParticleChildEmitters; diff --git a/src/particleemitterprop.h b/src/particleemitterprop.h index 78f349b8..6a9d6ecb 100644 --- a/src/particleemitterprop.h +++ b/src/particleemitterprop.h @@ -37,17 +37,20 @@ enum ChangeFunc template <typename T> struct ParticleEmitterProp { + explicit ParticleEmitterProp(T value = T()) + : ParticleEmitterProp(value, value) + {} + + ParticleEmitterProp(T min, T max) + : minVal(min), maxVal(max) + {} + void set(T min, T max) { minVal = min; maxVal = max; } - void set(T val) - { - set(val, val); - } - void setFunction(ChangeFunc func, T amplitude, int period, int phase) { changeFunc = func; |