[Tizen] Reduce Dali::Animation reference count at PlayList 27/311927/1 accepted/tizen/7.0/unified/20240531.044453
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 30 May 2024 12:51:51 +0000 (21:51 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 30 May 2024 12:51:51 +0000 (21:51 +0900)
Change-Id: I107ea63ebd910c1459b38718549a8d1b6d23c29a
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/common/core-impl.cpp
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animation-playlist.cpp
dali/internal/event/animation/animation-playlist.h

index e1fca46..f70f11a 100644 (file)
@@ -309,6 +309,9 @@ void Core::ProcessEvents()
   // Flush any queued messages for the update-thread
   const bool messagesToProcess = mUpdateManager->FlushQueue();
 
+  // Notify to animation play list that event processing has finished.
+  mAnimationPlaylist->EventLoopFinished();
+
   // Check if the touch or gestures require updates.
   const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
 
index 7ef3323..c455125 100644 (file)
@@ -404,7 +404,7 @@ void Animation::Clear()
   mNotificationCount = 0;
 
   // Update the current playlist
-  mPlaylist.OnClear(*this);
+  mPlaylist.OnClear(*this, true);
 }
 
 void Animation::AnimateBy(Property& target, Property::Value relativeValue)
index 17e47ff..a246c0b 100644 (file)
@@ -51,21 +51,31 @@ void AnimationPlaylist::AnimationDestroyed(Animation& animation)
 
 void AnimationPlaylist::OnPlay(Animation& animation)
 {
-  mPlaylist.push_back(Dali::Animation(&animation));
+  mPlaylist.insert(Dali::Animation(&animation));
 }
 
-void AnimationPlaylist::OnClear(Animation& animation)
+void AnimationPlaylist::OnClear(Animation& animation, bool ignoreRequired)
 {
-  std::vector<Dali::Animation>::iterator iter = std::find(mPlaylist.begin(), mPlaylist.end(), Dali::Animation(&animation));
-  std::vector<Dali::Animation>::iterator last = mPlaylist.end();
-  if(iter != last)
+  // Keep handle for safety.
+  auto handle = Dali::Animation(&animation);
+
+  auto iter = mPlaylist.find(handle);
+  if(iter != mPlaylist.end())
+  {
+    mPlaylist.erase(iter);
+  }
+
+  if(ignoreRequired)
   {
-    --last;                  // move to real last
-    std::swap(*iter, *last); // swap
-    mPlaylist.resize(mPlaylist.size() - 1u);
+    mIgnoredAnimations.insert(&animation);
   }
 }
 
+void AnimationPlaylist::EventLoopFinished()
+{
+  mIgnoredAnimations.clear();
+}
+
 void AnimationPlaylist::NotifyCompleted()
 {
   std::vector<Dali::Animation> finishedAnimations;
@@ -76,15 +86,15 @@ void AnimationPlaylist::NotifyCompleted()
   {
     Animation* animation = *iter;
 
-    if(animation->HasFinished())
+    if(mIgnoredAnimations.find(animation) == mIgnoredAnimations.end() && animation->HasFinished())
     {
-      finishedAnimations.push_back(Dali::Animation(animation));
+      Dali::Animation handle(animation);
+
+      finishedAnimations.push_back(handle);
 
       // The animation may be present in mPlaylist - remove if necessary
       // Note that the animation "Finish" signal is emitted after Stop() has been called
-      std::vector<Dali::Animation>::iterator iter = std::find(mPlaylist.begin(), mPlaylist.end(), Dali::Animation(animation));
-      DALI_ASSERT_DEBUG(iter != mPlaylist.end());
-      mPlaylist.erase(iter);
+      OnClear(*animation, false);
     }
   }
 
index ad3e3d7..6ea6a8f 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/common/set-wrapper.h>
 #include <dali/internal/common/message.h>
 #include <dali/internal/event/common/complete-notification-interface.h>
 #include <dali/public-api/animation/animation.h>
@@ -72,9 +73,17 @@ public:
 
   /**
    * Called when an animation is cleared.
+   * @param[in] animation The animation that is cleared.
+   * @param[in] ignoreRequired Whether to ignore the notify for current event loop, or not.
    * @post The animation will no longer be referenced by AnimationPlaylist.
    */
-  void OnClear(Animation& animation);
+  void OnClear(Animation& animation, bool ignoreRequired);
+
+  /**
+   * Notify from core that current event loop finisehd.
+   * It will clear all ignored animations at OnClear.
+   */
+  void EventLoopFinished();
 
   /**
    * @brief Notify that an animation has reached a progress marker
@@ -117,7 +126,8 @@ private: // from CompleteNotificationInterface
 
 private:
   Dali::Vector<Animation*>     mAnimations; ///< All existing animations (not owned)
-  std::vector<Dali::Animation> mPlaylist;   ///< The currently playing animations (owned through handle)
+  std::set<Dali::Animation> mPlaylist;   ///< The currently playing animations (owned through handle)
+  std::set<Animation*>     mIgnoredAnimations; ///< The currently cleard animations. We should not send notification at NotifyCompleted.
 };
 
 /**