Browse Source

Fix ParticleEmitter finish event not working when emission is explicitly disabled with SetEmitting(false). Cleanup ParticleEmitter code. Closes #1854.

Lasse Öörni 8 years ago
parent
commit
5f0b5a6211

+ 30 - 28
Source/Urho3D/Graphics/ParticleEmitter.cpp

@@ -297,7 +297,9 @@ void ParticleEmitter::SetEmitting(bool enable)
     if (enable != emitting_)
     if (enable != emitting_)
     {
     {
         emitting_ = enable;
         emitting_ = enable;
-        sendFinishedEvent_ = enable;
+
+        // If stopping emission now, and there are active particles, send finish event once they are gone
+        sendFinishedEvent_ = enable || CheckActiveParticles();
         periodTimer_ = 0.0f;
         periodTimer_ = 0.0f;
         // Note: network update does not need to be marked as this is a file only attribute
         // Note: network update does not need to be marked as this is a file only attribute
     }
     }
@@ -531,6 +533,20 @@ unsigned ParticleEmitter::GetFreeParticle() const
     return M_MAX_UNSIGNED;
     return M_MAX_UNSIGNED;
 }
 }
 
 
+bool ParticleEmitter::CheckActiveParticles() const
+{
+    for (unsigned i = 0; i < billboards_.Size(); ++i)
+    {
+        if (billboards_[i].enabled_)
+        {
+            return true;
+            break;
+        }
+    }
+
+    return false;
+}
+
 void ParticleEmitter::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
 void ParticleEmitter::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
 {
 {
     // Store scene's timestep and use it instead of global timestep, as time scale may be other than 1
     // Store scene's timestep and use it instead of global timestep, as time scale may be other than 1
@@ -546,40 +562,26 @@ void ParticleEmitter::HandleScenePostUpdate(StringHash eventType, VariantMap& ev
         MarkForUpdate();
         MarkForUpdate();
     }
     }
 
 
-    if (node_ && !emitting_ && sendFinishedEvent_)
+    // Send finished event only once all particles are gone
+    if (node_ && !emitting_ && sendFinishedEvent_ && !CheckActiveParticles())
     {
     {
-        // Send finished event only once all billboards are gone
-        bool hasEnabledBillboards = false;
+        sendFinishedEvent_ = false;
 
 
-        for (unsigned i = 0; i < billboards_.Size(); ++i)
-        {
-            if (billboards_[i].enabled_)
-            {
-                hasEnabledBillboards = true;
-                break;
-            }
-        }
+        // Make a weak pointer to self to check for destruction during event handling
+        WeakPtr<ParticleEmitter> self(this);
 
 
-        if (!hasEnabledBillboards)
-        {
-            sendFinishedEvent_ = false;
-
-            // Make a weak pointer to self to check for destruction during event handling
-            WeakPtr<ParticleEmitter> self(this);
+        using namespace ParticleEffectFinished;
 
 
-            using namespace ParticleEffectFinished;
+        VariantMap& eventData = GetEventDataMap();
+        eventData[P_NODE] = node_;
+        eventData[P_EFFECT] = effect_;
 
 
-            VariantMap& eventData = GetEventDataMap();
-            eventData[P_NODE] = node_;
-            eventData[P_EFFECT] = effect_;
+        node_->SendEvent(E_PARTICLEEFFECTFINISHED, eventData);
 
 
-            node_->SendEvent(E_PARTICLEEFFECTFINISHED, eventData);
+        if (self.Expired())
+            return;
 
 
-            if (self.Expired())
-                return;
-
-            DoAutoRemove(autoRemove_);
-        }
+        DoAutoRemove(autoRemove_);
     }
     }
 }
 }
 
 

+ 2 - 0
Source/Urho3D/Graphics/ParticleEmitter.h

@@ -121,6 +121,8 @@ protected:
     bool EmitNewParticle();
     bool EmitNewParticle();
     /// Return a free particle index.
     /// Return a free particle index.
     unsigned GetFreeParticle() const;
     unsigned GetFreeParticle() const;
+    /// Return whether has active particles.
+    bool CheckActiveParticles() const;
 
 
 private:
 private:
     /// Handle scene post-update event.
     /// Handle scene post-update event.