Browse Source

rename variant name, avoid memory leak when attribute not found.

aster 11 years ago
parent
commit
06ccf8efbb

+ 32 - 9
Source/Engine/Graphics/Material.cpp

@@ -444,10 +444,33 @@ void Material::SetShaderParameter(const String& name, const Variant& value)
 
 
 void Material::SetShaderParameterAnimation(const String& name, ValueAnimation* animation, WrapMode wrapMode, float speed)
 void Material::SetShaderParameterAnimation(const String& name, ValueAnimation* animation, WrapMode wrapMode, float speed)
 {
 {
-    if (shaderParameters_.Find(name) == shaderParameters_.End())
-        return;
+    ShaderParameterAnimationInfo* info = GetShaderParameterAnimationInfo(name);
 
 
-    shaderParameterAnimationInfos_[name] = new ShaderParameterAnimationInfo(this, name, animation, wrapMode, speed);
+    if (animation)
+    {
+        if (info && info->GetAnimation() == animation)
+        {
+            info->SetWrapMode(wrapMode);
+            info->SetSpeed(speed);
+            return;
+        }
+
+        // Use shared ptr to avoid memory leak
+        SharedPtr<ValueAnimation> animationPtr(animation);
+
+        if (shaderParameters_.Find(name) == shaderParameters_.End())
+        {
+            LOGERROR(GetName() + " has no shader parameter: " + name);
+            return;
+        }
+
+        shaderParameterAnimationInfos_[name] = new ShaderParameterAnimationInfo(this, name, animationPtr, wrapMode, speed);
+    }
+    else
+    {
+        if (info)
+            shaderParameterAnimationInfos_.Erase(name);
+    }
 }
 }
 
 
 void Material::SetShaderParameterAnimationWrapMode(const String& name, WrapMode wrapMode)
 void Material::SetShaderParameterAnimationWrapMode(const String& name, WrapMode wrapMode)
@@ -621,20 +644,20 @@ const Variant& Material::GetShaderParameter(const String& name) const
 
 
 ValueAnimation* Material::GetShaderParameterAnimation(const String& name) const
 ValueAnimation* Material::GetShaderParameterAnimation(const String& name) const
 {
 {
-    ShaderParameterAnimationInfo* instance = GetShaderParameterAnimationInfo(name);
-    return instance == 0 ? 0 : instance->GetAnimation();
+    ShaderParameterAnimationInfo* info = GetShaderParameterAnimationInfo(name);
+    return info == 0 ? 0 : info->GetAnimation();
 }
 }
 
 
 WrapMode Material::GetShaderParameterAnimationWrapMode(const String& name) const
 WrapMode Material::GetShaderParameterAnimationWrapMode(const String& name) const
 {
 {
-    ShaderParameterAnimationInfo* instance = GetShaderParameterAnimationInfo(name);
-    return instance == 0 ? WM_LOOP : instance->GetWrapMode();
+    ShaderParameterAnimationInfo* info = GetShaderParameterAnimationInfo(name);
+    return info == 0 ? WM_LOOP : info->GetWrapMode();
 }
 }
 
 
 float Material::GetShaderParameterAnimationSpeed(const String& name) const
 float Material::GetShaderParameterAnimationSpeed(const String& name) const
 {
 {
-    ShaderParameterAnimationInfo* instance = GetShaderParameterAnimationInfo(name);
-    return instance == 0 ? 0 : instance->GetSpeed();
+    ShaderParameterAnimationInfo* info = GetShaderParameterAnimationInfo(name);
+    return info == 0 ? 0 : info->GetSpeed();
 }
 }
 
 
 String Material::GetTextureUnitName(TextureUnit unit)
 String Material::GetTextureUnitName(TextureUnit unit)

+ 1 - 1
Source/Engine/Graphics/Material.h

@@ -66,7 +66,7 @@ struct TechniqueEntry
     float lodDistance_;
     float lodDistance_;
 };
 };
 
 
-/// Material shader parameter animation instance.
+/// Material shader parameter animation info.
 class ShaderParameterAnimationInfo : public ValueAnimationInfo
 class ShaderParameterAnimationInfo : public ValueAnimationInfo
 {
 {
 public:
 public:

+ 35 - 32
Source/Engine/Scene/Animatable.cpp

@@ -109,7 +109,7 @@ bool Animatable::LoadXML(const XMLElement& source, bool setInstanceDefault)
         return false;
         return false;
 
 
     SetObjectAnimation(0);
     SetObjectAnimation(0);
-    attributeAnimationInstances_.Clear();
+    attributeAnimationInfos_.Clear();
 
 
     XMLElement elem = source.GetChild("objectanimation");
     XMLElement elem = source.GetChild("objectanimation");
     if (elem)
     if (elem)
@@ -162,7 +162,7 @@ bool Animatable::SaveXML(XMLElement& dest) const
             return false;
             return false;
     }
     }
 
 
-    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInstances_.Begin(); i != attributeAnimationInstances_.End(); ++i)
+    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInfos_.Begin(); i != attributeAnimationInfos_.End(); ++i)
     {
     {
         ValueAnimation* attributeAnimation = i->second_->GetAnimation();
         ValueAnimation* attributeAnimation = i->second_->GetAnimation();
         if (attributeAnimation->GetOwner())
         if (attributeAnimation->GetOwner())
@@ -197,21 +197,24 @@ void Animatable::SetObjectAnimation(ObjectAnimation* objectAnimation)
 
 
 void Animatable::SetAttributeAnimation(const String& name, ValueAnimation* attributeAnimation, WrapMode wrapMode, float speed)
 void Animatable::SetAttributeAnimation(const String& name, ValueAnimation* attributeAnimation, WrapMode wrapMode, float speed)
 {
 {
-    AttributeAnimationInfo* currentInstance = GetAttributeAnimationInstance(name);
+    AttributeAnimationInfo* info = GetAttributeAnimationInfo(name);
 
 
     if (attributeAnimation)
     if (attributeAnimation)
     {
     {
-        if (currentInstance && attributeAnimation == currentInstance->GetAnimation())
+        if (info && attributeAnimation == info->GetAnimation())
         {
         {
-            currentInstance->SetWrapMode(wrapMode);
-            currentInstance->SetSpeed(speed);
+            info->SetWrapMode(wrapMode);
+            info->SetSpeed(speed);
             return;
             return;
         }
         }
 
 
+        // Use shared ptr to avoid memory leak
+        SharedPtr<ValueAnimation> animationPtr(attributeAnimation);
+
         // Get attribute info
         // Get attribute info
         const AttributeInfo* attributeInfo = 0;
         const AttributeInfo* attributeInfo = 0;
-        if (currentInstance)
-            attributeInfo = &currentInstance->GetAttributeInfo();
+        if (info)
+            attributeInfo = &info->GetAttributeInfo();
         else
         else
         {
         {
             const Vector<AttributeInfo>* attributes = GetAttributes();
             const Vector<AttributeInfo>* attributes = GetAttributes();
@@ -238,7 +241,7 @@ void Animatable::SetAttributeAnimation(const String& name, ValueAnimation* attri
         }
         }
 
 
         // Check value type is same with attribute type
         // Check value type is same with attribute type
-        if (attributeAnimation->GetValueType() != attributeInfo->type_)
+        if (animationPtr->GetValueType() != attributeInfo->type_)
         {
         {
             LOGERROR("Invalid value type");
             LOGERROR("Invalid value type");
             return;
             return;
@@ -248,37 +251,37 @@ void Animatable::SetAttributeAnimation(const String& name, ValueAnimation* attri
         if (attributeInfo->mode_ & AM_NET)
         if (attributeInfo->mode_ & AM_NET)
             animatedNetworkAttributes_.Insert(attributeInfo);
             animatedNetworkAttributes_.Insert(attributeInfo);
 
 
-        attributeAnimationInstances_[name] = new AttributeAnimationInfo(this, *attributeInfo, attributeAnimation, wrapMode, speed);
+        attributeAnimationInfos_[name] = new AttributeAnimationInfo(this, *attributeInfo, animationPtr, wrapMode, speed);
 
 
-        if (!currentInstance)
+        if (!info)
             OnAttributeAnimationAdded();
             OnAttributeAnimationAdded();
     }
     }
     else
     else
     {
     {
-        if (!currentInstance)
+        if (!info)
             return;
             return;
 
 
         // Remove network attribute from set
         // Remove network attribute from set
-        if (currentInstance->GetAttributeInfo().mode_ & AM_NET)
-            animatedNetworkAttributes_.Erase(&currentInstance->GetAttributeInfo());
+        if (info->GetAttributeInfo().mode_ & AM_NET)
+            animatedNetworkAttributes_.Erase(&info->GetAttributeInfo());
 
 
-        attributeAnimationInstances_.Erase(name);
+        attributeAnimationInfos_.Erase(name);
         OnAttributeAnimationRemoved();
         OnAttributeAnimationRemoved();
     }
     }
 }
 }
 
 
 void Animatable::SetAttributeAnimationWrapMode(const String& name, WrapMode wrapMode)
 void Animatable::SetAttributeAnimationWrapMode(const String& name, WrapMode wrapMode)
 {
 {
-    AttributeAnimationInfo* currentInstance = GetAttributeAnimationInstance(name);
-    if (currentInstance)
-        currentInstance->SetWrapMode(wrapMode);
+    AttributeAnimationInfo* info = GetAttributeAnimationInfo(name);
+    if (info)
+        info->SetWrapMode(wrapMode);
 }
 }
 
 
 void Animatable::SetAttributeAnimationSpeed(const String& name, float speed)
 void Animatable::SetAttributeAnimationSpeed(const String& name, float speed)
 {
 {
-    AttributeAnimationInfo* currentInstance = GetAttributeAnimationInstance(name);
-    if (currentInstance)
-        currentInstance->SetSpeed(speed);
+    AttributeAnimationInfo* info = GetAttributeAnimationInfo(name);
+    if (info)
+        info->SetSpeed(speed);
 }
 }
 
 
 ObjectAnimation* Animatable::GetObjectAnimation() const
 ObjectAnimation* Animatable::GetObjectAnimation() const
@@ -288,20 +291,20 @@ ObjectAnimation* Animatable::GetObjectAnimation() const
 
 
 ValueAnimation* Animatable::GetAttributeAnimation(const String& name) const
 ValueAnimation* Animatable::GetAttributeAnimation(const String& name) const
 {
 {
-    const AttributeAnimationInfo* instance = GetAttributeAnimationInstance(name);
-    return instance ? instance->GetAnimation() : 0;
+    const AttributeAnimationInfo* info = GetAttributeAnimationInfo(name);
+    return info ? info->GetAnimation() : 0;
 }
 }
 
 
 WrapMode Animatable::GetAttributeAnimationWrapMode(const String& name) const
 WrapMode Animatable::GetAttributeAnimationWrapMode(const String& name) const
 {
 {
-    const AttributeAnimationInfo* instance = GetAttributeAnimationInstance(name);
-    return instance ? instance->GetWrapMode() : WM_LOOP;
+    const AttributeAnimationInfo* info = GetAttributeAnimationInfo(name);
+    return info ? info->GetWrapMode() : WM_LOOP;
 }
 }
 
 
 float Animatable::GetAttributeAnimationSpeed(const String& name) const
 float Animatable::GetAttributeAnimationSpeed(const String& name) const
 {
 {
-    const AttributeAnimationInfo* instance = GetAttributeAnimationInstance(name);
-    return instance ? instance->GetSpeed() : 1.0f;
+    const AttributeAnimationInfo* info = GetAttributeAnimationInfo(name);
+    return info ? info->GetSpeed() : 1.0f;
 }
 }
 
 
 void Animatable::SetObjectAnimationAttr(ResourceRef value)
 void Animatable::SetObjectAnimationAttr(ResourceRef value)
@@ -340,7 +343,7 @@ void Animatable::OnObjectAnimationRemoved(ObjectAnimation* objectAnimation)
 
 
     // Just remove all attribute animations from the object animation
     // Just remove all attribute animations from the object animation
     Vector<String> names;
     Vector<String> names;
-    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::Iterator i = attributeAnimationInstances_.Begin(); i != attributeAnimationInstances_.End(); ++i)
+    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::Iterator i = attributeAnimationInfos_.Begin(); i != attributeAnimationInfos_.End(); ++i)
     {
     {
         if (i->second_->GetAnimation()->GetOwner() == objectAnimation)
         if (i->second_->GetAnimation()->GetOwner() == objectAnimation)
             names.Push(i->first_);
             names.Push(i->first_);
@@ -356,7 +359,7 @@ void Animatable::UpdateAttributeAnimations(float timeStep)
         return;
         return;
 
 
     Vector<String> finishedNames;
     Vector<String> finishedNames;
-    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInstances_.Begin(); i != attributeAnimationInstances_.End(); ++i)
+    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInfos_.Begin(); i != attributeAnimationInfos_.End(); ++i)
     {
     {
         if (i->second_->Update(timeStep))
         if (i->second_->Update(timeStep))
             finishedNames.Push(i->second_->GetAttributeInfo().name_);
             finishedNames.Push(i->second_->GetAttributeInfo().name_);
@@ -371,10 +374,10 @@ bool Animatable::IsAnimatedNetworkAttribute(const AttributeInfo& attrInfo) const
     return animatedNetworkAttributes_.Find(&attrInfo) != animatedNetworkAttributes_.End();
     return animatedNetworkAttributes_.Find(&attrInfo) != animatedNetworkAttributes_.End();
 }
 }
 
 
-AttributeAnimationInfo* Animatable::GetAttributeAnimationInstance(const String& name) const
+AttributeAnimationInfo* Animatable::GetAttributeAnimationInfo(const String& name) const
 {
 {
-    HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInstances_.Find(name);
-    if (i != attributeAnimationInstances_.End())
+    HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInfos_.Find(name);
+    if (i != attributeAnimationInfos_.End())
         return i->second_;
         return i->second_;
 
 
     return 0;
     return 0;

+ 4 - 4
Source/Engine/Scene/Animatable.h

@@ -122,8 +122,8 @@ protected:
     void UpdateAttributeAnimations(float timeStep);
     void UpdateAttributeAnimations(float timeStep);
     /// Is animated network attribute.
     /// Is animated network attribute.
     bool IsAnimatedNetworkAttribute(const AttributeInfo& attrInfo) const;
     bool IsAnimatedNetworkAttribute(const AttributeInfo& attrInfo) const;
-    /// Return attribute animation instance.
-    AttributeAnimationInfo* GetAttributeAnimationInstance(const String& name) const;
+    /// Return attribute animation info.
+    AttributeAnimationInfo* GetAttributeAnimationInfo(const String& name) const;
 
 
     /// Animation enabled.
     /// Animation enabled.
     bool animationEnabled_;
     bool animationEnabled_;
@@ -131,8 +131,8 @@ protected:
     SharedPtr<ObjectAnimation> objectAnimation_;
     SharedPtr<ObjectAnimation> objectAnimation_;
     /// Animated network attribute set.
     /// Animated network attribute set.
     HashSet<const AttributeInfo*> animatedNetworkAttributes_;
     HashSet<const AttributeInfo*> animatedNetworkAttributes_;
-    /// Attribute animation instances.
-    HashMap<String, SharedPtr<AttributeAnimationInfo> > attributeAnimationInstances_;
+    /// Attribute animation infos.
+    HashMap<String, SharedPtr<AttributeAnimationInfo> > attributeAnimationInfos_;
 };
 };
 
 
 }
 }

+ 2 - 2
Source/Engine/Scene/Component.cpp

@@ -201,13 +201,13 @@ void Component::MarkNetworkUpdate()
 
 
 void Component::OnAttributeAnimationAdded()
 void Component::OnAttributeAnimationAdded()
 {
 {
-    if (attributeAnimationInstances_.Size() == 1)
+    if (attributeAnimationInfos_.Size() == 1)
         SubscribeToEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE, HANDLER(Component, HandleAttributeAnimationUpdate));        
         SubscribeToEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE, HANDLER(Component, HandleAttributeAnimationUpdate));        
 }
 }
 
 
 void Component::OnAttributeAnimationRemoved()
 void Component::OnAttributeAnimationRemoved()
 {
 {
-    if (attributeAnimationInstances_.Empty())
+    if (attributeAnimationInfos_.Empty())
         UnsubscribeFromEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE);
         UnsubscribeFromEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE);
 }
 }
 
 

+ 2 - 2
Source/Engine/Scene/Node.cpp

@@ -1446,13 +1446,13 @@ unsigned Node::GetNumPersistentComponents() const
 
 
 void Node::OnAttributeAnimationAdded()
 void Node::OnAttributeAnimationAdded()
 {
 {
-    if (attributeAnimationInstances_.Size() == 1)
+    if (attributeAnimationInfos_.Size() == 1)
         SubscribeToEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE, HANDLER(Node, HandleAttributeAnimationUpdate));        
         SubscribeToEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE, HANDLER(Node, HandleAttributeAnimationUpdate));        
 }
 }
 
 
 void Node::OnAttributeAnimationRemoved()
 void Node::OnAttributeAnimationRemoved()
 {
 {
-    if (attributeAnimationInstances_.Empty())
+    if (attributeAnimationInfos_.Empty())
         UnsubscribeFromEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE);
         UnsubscribeFromEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE);
 }
 }
 
 

+ 2 - 2
Source/Engine/UI/UIElement.cpp

@@ -1584,13 +1584,13 @@ UIElement* UIElement::GetElementEventSender() const
 
 
 void UIElement::OnAttributeAnimationAdded()
 void UIElement::OnAttributeAnimationAdded()
 {
 {
-    if (attributeAnimationInstances_.Size() == 1)
+    if (attributeAnimationInfos_.Size() == 1)
         SubscribeToEvent(E_POSTUPDATE, HANDLER(UIElement, HandlePostUpdate));
         SubscribeToEvent(E_POSTUPDATE, HANDLER(UIElement, HandlePostUpdate));
 }
 }
 
 
 void UIElement::OnAttributeAnimationRemoved()
 void UIElement::OnAttributeAnimationRemoved()
 {
 {
-    if (attributeAnimationInstances_.Empty())
+    if (attributeAnimationInfos_.Empty())
         UnsubscribeFromEvent(E_POSTUPDATE);
         UnsubscribeFromEvent(E_POSTUPDATE);
 }
 }