Browse Source

Fixes memory leak exposed when using either AnimationController#destroyAnimation(Animation*) and AnimationController::destroyAllAnimations().
Animation deleted properly when deleted from AnimationController.
Animation data deleted when target is deleted.
Animation data deleted when scene deleted.

Kieran Cunney 14 năm trước cách đây
mục cha
commit
5f5eea693f

+ 0 - 1
gameplay/src/Animation.cpp

@@ -67,7 +67,6 @@ Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int p
 Animation::Channel::~Channel()
 Animation::Channel::~Channel()
 {
 {
     SAFE_DELETE(_curve);
     SAFE_DELETE(_curve);
-    _animation->removeChannel(this);
     SAFE_RELEASE(_animation);
     SAFE_RELEASE(_animation);
 }
 }
 
 

+ 1 - 0
gameplay/src/Animation.h

@@ -92,6 +92,7 @@ private:
      */
      */
     class Channel
     class Channel
     {
     {
+        friend class AnimationController;
         friend class AnimationClip;
         friend class AnimationClip;
         friend class Animation;
         friend class Animation;
         friend class AnimationTarget;
         friend class AnimationTarget;

+ 42 - 17
gameplay/src/AnimationController.cpp

@@ -13,7 +13,14 @@ AnimationController::AnimationController()
 
 
 AnimationController::~AnimationController()
 AnimationController::~AnimationController()
 {
 {
-    destroyAllAnimations();
+    std::vector<Animation*>::iterator itr = _animations.begin();
+    for ( ; itr != _animations.end(); itr++)
+    {
+        Animation* temp = *itr;
+        SAFE_RELEASE(temp);
+    }
+
+    _animations.clear();
 }
 }
 
 
 Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
 Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
@@ -111,12 +118,9 @@ void AnimationController::stopAllAnimations()
     while (clipIter != _runningClips.end())
     while (clipIter != _runningClips.end())
     {
     {
         AnimationClip* clip = *clipIter;
         AnimationClip* clip = *clipIter;
-        clipIter++;
         clip->stop();
         clip->stop();
+        clipIter++;
     }
     }
-    _runningClips.clear();
-
-    _state = IDLE;
 }
 }
 
 
 Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, Properties* animationProperties)
 Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, Properties* animationProperties)
@@ -269,7 +273,13 @@ void AnimationController::initialize()
 
 
 void AnimationController::finalize()
 void AnimationController::finalize()
 {
 {
-    stopAllAnimations();
+    std::list<AnimationClip*>::iterator itr = _runningClips.begin();
+    for ( ; itr != _runningClips.end(); itr++)
+    {
+        AnimationClip* clip = *itr;
+        SAFE_RELEASE(clip);
+    }
+    _runningClips.clear();
     _state = STOPPED;
     _state = STOPPED;
 }
 }
 
 
@@ -366,30 +376,45 @@ void AnimationController::addAnimation(Animation* animation)
 
 
 void AnimationController::destroyAnimation(Animation* animation)
 void AnimationController::destroyAnimation(Animation* animation)
 {
 {
-    std::vector<Animation*>::iterator itr = _animations.begin();
+    assert(animation);
+
+    std::vector<Animation::Channel*>::iterator cItr = animation->_channels.begin();
+    for (; cItr != animation->_channels.end(); cItr++)
+    {
+        Animation::Channel* channel = *cItr;
+        channel->_target->deleteChannel(channel);
+    }
 
 
-    while (itr != _animations.end())
+    std::vector<Animation*>::iterator aItr = _animations.begin();
+    while (aItr != _animations.end())
     {
     {
-        if (animation == *itr)
+        if (animation == *aItr)
         {
         {
-            Animation* animation = *itr;
-            _animations.erase(itr);
-            SAFE_RELEASE(animation);
+            Animation* temp = *aItr;
+            SAFE_RELEASE(temp);
+            _animations.erase(aItr);
             return;
             return;
         }
         }
-        itr++;
+        aItr++;
     }
     }
 }
 }
 
 
 void AnimationController::destroyAllAnimations()
 void AnimationController::destroyAllAnimations()
 {
 {
-    std::vector<Animation*>::iterator itr = _animations.begin();
+    std::vector<Animation*>::iterator aItr = _animations.begin();
     
     
-    while (itr != _animations.end())
+    while (aItr != _animations.end())
     {
     {
-        Animation* animation = *itr;
+        Animation* animation = *aItr;
+        std::vector<Animation::Channel*>::iterator cItr = animation->_channels.begin();
+        for (; cItr != animation->_channels.end(); cItr++)
+        {
+            Animation::Channel* channel = *cItr;
+            channel->_target->deleteChannel(channel);
+        }
+
         SAFE_RELEASE(animation);
         SAFE_RELEASE(animation);
-        itr++;
+        aItr++;
     }
     }
 
 
     _animations.clear();
     _animations.clear();

+ 23 - 0
gameplay/src/AnimationTarget.cpp

@@ -19,6 +19,7 @@ AnimationTarget::~AnimationTarget()
         while (itr != _animationChannels->end())
         while (itr != _animationChannels->end())
         {
         {
             Animation::Channel* channel = (*itr);
             Animation::Channel* channel = (*itr);
+            channel->_animation->removeChannel(channel);
             SAFE_DELETE(channel);
             SAFE_DELETE(channel);
             itr++;
             itr++;
         }
         }
@@ -95,6 +96,28 @@ int AnimationTarget::getPropertyId(TargetType type, const char* propertyIdStr)
     return -1;
     return -1;
 }
 }
 
 
+void AnimationTarget::deleteChannel(Animation::Channel* channel)
+{
+    if (_animationChannels)
+    {
+        std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
+        for ( ; itr != _animationChannels->end(); itr++)
+        {
+            Animation::Channel* temp = *itr;
+            if (channel == temp)
+            {
+                SAFE_DELETE(channel);
+                _animationChannels->erase(itr);
+
+                if (_animationChannels->empty())
+                    SAFE_DELETE(_animationChannels);
+
+                return;
+            }
+        }
+    }
+}
+
 }
 }
 
 
 
 

+ 2 - 0
gameplay/src/AnimationTarget.h

@@ -67,6 +67,8 @@ protected:
 
 
     void addChannel(Animation::Channel* animation);
     void addChannel(Animation::Channel* animation);
 
 
+    void deleteChannel(Animation::Channel* channel);
+
     TargetType _targetType;             // The type of target this is.
     TargetType _targetType;             // The type of target this is.
 
 
     char _animationPropertyBitFlag;     // Bit flag used to indicate which properties on the AnimationTarget are currently animating.
     char _animationPropertyBitFlag;     // Bit flag used to indicate which properties on the AnimationTarget are currently animating.