Browse Source

Fix material removal while handling attribute animation causing potential crash. Fix material animation event being transmitted already on the first frame.

Lasse Öörni 9 years ago
parent
commit
ce78e3217c

+ 9 - 1
Source/Urho3D/Graphics/Material.cpp

@@ -1362,11 +1362,19 @@ void Material::HandleAttributeAnimationUpdate(StringHash eventType, VariantMap&
     // Timestep parameter is same no matter what event is being listened to
     // Timestep parameter is same no matter what event is being listened to
     float timeStep = eventData[Update::P_TIMESTEP].GetFloat();
     float timeStep = eventData[Update::P_TIMESTEP].GetFloat();
 
 
+    // Keep weak pointer to self to check for destruction caused by event handling
+    WeakPtr<Object> self(this);
+
     Vector<String> finishedNames;
     Vector<String> finishedNames;
     for (HashMap<StringHash, SharedPtr<ShaderParameterAnimationInfo> >::ConstIterator i = shaderParameterAnimationInfos_.Begin();
     for (HashMap<StringHash, SharedPtr<ShaderParameterAnimationInfo> >::ConstIterator i = shaderParameterAnimationInfos_.Begin();
          i != shaderParameterAnimationInfos_.End(); ++i)
          i != shaderParameterAnimationInfos_.End(); ++i)
     {
     {
-        if (i->second_->Update(timeStep))
+        bool finished = i->second_->Update(timeStep);
+        // If self deleted as a result of an event sent during animation playback, nothing more to do
+        if (self.Expired())
+            return;
+
+        if (finished)
             finishedNames.Push(i->second_->GetName());
             finishedNames.Push(i->second_->GetName());
     }
     }
 
 

+ 2 - 1
Source/Urho3D/Scene/ValueAnimationInfo.cpp

@@ -161,7 +161,8 @@ void ValueAnimationInfo::GetEventFrames(float beginTime, float endTime, PODVecto
     switch (wrapMode_)
     switch (wrapMode_)
     {
     {
     case WM_LOOP:
     case WM_LOOP:
-        if (beginTime < endTime)
+        /// \todo This can miss an event if the deltatime is exactly the animation's length
+        if (beginTime <= endTime)
             animation_->GetEventFrames(beginTime, endTime, eventFrames);
             animation_->GetEventFrames(beginTime, endTime, eventFrames);
         else
         else
         {
         {