upgrade emitters garbage collection

This commit is contained in:
MihailRis
2024-12-23 17:26:22 +03:00
parent 78761a445a
commit 52494a680c
3 changed files with 21 additions and 12 deletions
+6 -1
View File
@@ -19,7 +19,7 @@ Emitter::Emitter(
)
: level(level),
origin(std::move(origin)),
prototype({this, 0, glm::vec3(), preset.velocity, preset.lifetime, region}),
prototype({this, 0, {}, preset.velocity, preset.lifetime, region}),
texture(texture),
count(count),
preset(std::move(preset)) {
@@ -113,6 +113,7 @@ void Emitter::update(
if (count > 0) {
count--;
}
refCount++;
}
}
@@ -124,6 +125,10 @@ bool Emitter::isDead() const {
return count == 0;
}
bool Emitter::isReferred() const {
return refCount > 0;
}
const EmitterOrigin& Emitter::getOrigin() const {
return origin;
}
+6
View File
@@ -54,6 +54,9 @@ class Emitter {
util::PseudoRandom random;
public:
/// @brief Number of references (alive particles)
int refCount = 0;
/// @brief Particle settings
ParticlesPreset preset;
Emitter(
@@ -86,6 +89,9 @@ public:
/// @return true if the emitter has spawned all particles
bool isDead() const;
/// @return true if there is at least one alive referring particle left
bool isReferred() const;
const EmitterOrigin& getOrigin() const;
void setOrigin(const EmitterOrigin& origin);
+9 -11
View File
@@ -63,7 +63,8 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
auto iter = vec.begin();
while (iter != vec.end()) {
auto& particle = *iter;
auto& preset = particle.emitter->preset;
auto& emitter = *particle.emitter;
auto& preset = emitter.preset;
if (!preset.frames.empty()) {
float time = preset.lifetime - particle.lifetime;
@@ -137,6 +138,7 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
);
if (particle.lifetime <= 0.0f) {
iter = vec.erase(iter);
emitter.refCount--;
} else {
iter++;
}
@@ -159,19 +161,15 @@ void ParticlesRenderer::render(const Camera& camera, float delta) {
auto iter = emitters.begin();
while (iter != emitters.end()) {
auto& emitter = *iter->second;
if (emitter.isDead() && !emitter.isReferred()) {
// destruct Emitter only when there is no particles spawned by it
iter = emitters.erase(iter);
continue;
}
auto texture = emitter.getTexture();
const auto& found = particles.find(texture);
std::vector<Particle>* vec;
if (found == particles.end()) {
if (emitter.isDead()) {
// destruct Emitter only when there is no particles spawned by it
iter = emitters.erase(iter);
continue;
}
vec = &particles[texture];
} else {
vec = &found->second;
}
vec = &particles[texture];
emitter.update(delta, camera.position, *vec);
iter++;
}