Bug 1415780 - Make AnimationEventDispatcher refcountable. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 27 Jan 2018 21:17:27 +0900
changeset 748024 3eba7ed427a1b6a5bef1ca2e6affb167d5e66976
parent 748023 d4eb8e0df51b62114d48566ce1a52102ae0b6ffa
child 748025 e7bc4f62b0d26c3a0369145ccbefcde8af3ba70f
push id97048
push userhikezoe@mozilla.com
push dateSat, 27 Jan 2018 12:23:10 +0000
reviewersbirtles
bugs1415780
milestone60.0a1
Bug 1415780 - Make AnimationEventDispatcher refcountable. r?birtles In a subsequent patch in this patch series, we want to make nsPresContext have an AnimationEventDispatcher as RefPtr<>. Instead, if we were trying to make nsPresContext have the AnimationEventDispatcher as data object (not RefPtr<>) just like we did in CommonAnimationManager, we will fall into header inclusion hell since Element.h includes nsPresContext.h and AnimationEventDispatcher.h ends up including Element.h. Even if we could solve the inclusion hell, we will suffer from Rust bindgen issues for some reasons. MozReview-Commit-ID: B0nX2JzIRJD
dom/animation/AnimationEventDispatcher.cpp
dom/animation/AnimationEventDispatcher.h
dom/animation/moz.build
layout/style/AnimationCommon.h
layout/style/nsAnimationManager.h
layout/style/nsTransitionManager.h
new file mode 100644
--- /dev/null
+++ b/dom/animation/AnimationEventDispatcher.cpp
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/AnimationEventDispatcher.h"
+
+#include "mozilla/EventDispatcher.h"
+
+namespace mozilla {
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(AnimationEventDispatcher)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AnimationEventDispatcher)
+  tmp->ClearEventQueue();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AnimationEventDispatcher)
+  for (auto& info : tmp->mPendingEvents) {
+    ImplCycleCollectionTraverse(cb, info.mElement,
+      "mozilla::AnimationEventDispatcher.mPendingEvents.mElement");
+    ImplCycleCollectionTraverse(cb, info.mAnimation,
+      "mozilla::AnimationEventDispatcher.mPendingEvents.mAnimation");
+  }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationEventDispatcher, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationEventDispatcher, Release)
+
+} // namespace mozilla
+
--- a/dom/animation/AnimationEventDispatcher.h
+++ b/dom/animation/AnimationEventDispatcher.h
@@ -94,16 +94,19 @@ struct AnimationEventInfo
   }
 };
 
 class AnimationEventDispatcher final
 {
 public:
   AnimationEventDispatcher() : mIsSorted(true) { }
 
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEventDispatcher)
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnimationEventDispatcher)
+
   void QueueEvents(nsTArray<AnimationEventInfo>&& aEvents)
   {
     mPendingEvents.AppendElements(Move(aEvents));
     mIsSorted = false;
   }
 
   // This is exposed as a separate method so that when we are dispatching
   // *both* transition events and animation events we can sort both lists
@@ -156,28 +159,19 @@ public:
 
   void ClearEventQueue()
   {
     mPendingEvents.Clear();
     mIsSorted = true;
   }
   bool HasQueuedEvents() const { return !mPendingEvents.IsEmpty(); }
 
-  // Methods for supporting cycle-collection
-  void Traverse(nsCycleCollectionTraversalCallback* aCallback,
-                const char* aName)
-  {
-    for (AnimationEventInfo& info : mPendingEvents) {
-      ImplCycleCollectionTraverse(*aCallback, info.mElement, aName);
-      ImplCycleCollectionTraverse(*aCallback, info.mAnimation, aName);
-    }
-  }
-  void Unlink() { ClearEventQueue(); }
+private:
+  ~AnimationEventDispatcher() = default;
 
-protected:
   class AnimationEventInfoLessThan
   {
   public:
     bool operator()(const AnimationEventInfo& a, const AnimationEventInfo& b) const
     {
       if (a.mTimeStamp != b.mTimeStamp) {
         // Null timestamps sort first
         if (a.mTimeStamp.IsNull() || b.mTimeStamp.IsNull()) {
@@ -192,26 +186,11 @@ protected:
     }
   };
 
   typedef nsTArray<AnimationEventInfo> EventArray;
   EventArray mPendingEvents;
   bool mIsSorted;
 };
 
-inline void
-ImplCycleCollectionUnlink(AnimationEventDispatcher& aField)
-{
-  aField.Unlink();
-}
-
-inline void
-ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
-                            AnimationEventDispatcher& aField,
-                            const char* aName,
-                            uint32_t aFlags = 0)
-{
-  aField.Traverse(&aCallback, aName);
-}
-
 } // namespace mozilla
 
 #endif // mozilla_AnimationEventDispatcher_h
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -42,16 +42,17 @@ EXPORTS.mozilla += [
     'TimingParams.h',
 ]
 
 UNIFIED_SOURCES += [
     'Animation.cpp',
     'AnimationEffectReadOnly.cpp',
     'AnimationEffectTiming.cpp',
     'AnimationEffectTimingReadOnly.cpp',
+    'AnimationEventDispatcher.cpp',
     'AnimationPerformanceWarning.cpp',
     'AnimationTimeline.cpp',
     'AnimationUtils.cpp',
     'AnimValuesStyleRule.cpp',
     'ComputedTimingFunction.cpp',
     'CSSPseudoElement.cpp',
     'DocumentTimeline.cpp',
     'EffectCompositor.cpp',
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -28,16 +28,17 @@ class Element;
 }
 
 template <class AnimationType>
 class CommonAnimationManager {
 public:
   explicit CommonAnimationManager(nsPresContext *aPresContext)
     : mPresContext(aPresContext)
   {
+    mEventDispatcher = new AnimationEventDispatcher();
   }
 
   // NOTE:  This can return null after Disconnect().
   nsPresContext* PresContext() const { return mPresContext; }
 
   /**
    * Notify the manager that the pres context is going away.
    */
@@ -69,21 +70,21 @@ public:
     collection->Destroy();
   }
 
   /**
    * Add pending events.
    */
   void QueueEvents(nsTArray<AnimationEventInfo>&& aEvents)
   {
-    mEventDispatcher.QueueEvents(Move(aEvents));
+    mEventDispatcher->QueueEvents(Move(aEvents));
   }
 
-  void SortEvents()      { mEventDispatcher.SortEvents(); }
-  void ClearEventQueue() { mEventDispatcher.ClearEventQueue(); }
+  void SortEvents()      { mEventDispatcher->SortEvents(); }
+  void ClearEventQueue() { mEventDispatcher->ClearEventQueue(); }
 
 protected:
   virtual ~CommonAnimationManager()
   {
     MOZ_ASSERT(!mPresContext, "Disconnect should have been called");
   }
 
   void AddElementCollection(AnimationCollection<AnimationType>* aCollection)
@@ -96,17 +97,17 @@ protected:
            mElementCollections.getFirst()) {
       head->Destroy(); // Note: this removes 'head' from mElementCollections.
     }
   }
 
   LinkedList<AnimationCollection<AnimationType>> mElementCollections;
   nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
 
-  mozilla::AnimationEventDispatcher mEventDispatcher;
+  RefPtr<mozilla::AnimationEventDispatcher> mEventDispatcher;
 };
 
 /**
  * Utility class for referencing the element that created a CSS animation or
  * transition. It is non-owning (i.e. it uses a raw pointer) since it is only
  * expected to be set by the owned animation while it actually being managed
  * by the owning element.
  *
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -308,17 +308,17 @@ public:
   void UpdateAnimations(
     mozilla::dom::Element* aElement,
     mozilla::CSSPseudoElementType aPseudoType,
     const mozilla::ServoStyleContext* aComputedValues);
 
   void DispatchEvents()
   {
     RefPtr<nsAnimationManager> kungFuDeathGrip(this);
-    mEventDispatcher.DispatchEvents(mPresContext);
+    mEventDispatcher->DispatchEvents(mPresContext);
   }
 
   // Utility function to walk through |aIter| to find the Keyframe with
   // matching offset and timing function but stopping as soon as the offset
   // differs from |aOffset| (i.e. it assumes a sorted iterator).
   //
   // If a matching Keyframe is found,
   //   Returns true and sets |aIndex| to the index of the matching Keyframe
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -361,17 +361,17 @@ public:
 
   bool InAnimationOnlyStyleUpdate() const {
     return mInAnimationOnlyStyleUpdate;
   }
 
   void DispatchEvents()
   {
     RefPtr<nsTransitionManager> kungFuDeathGrip(this);
-    mEventDispatcher.DispatchEvents(mPresContext);
+    mEventDispatcher->DispatchEvents(mPresContext);
   }
 
 protected:
   virtual ~nsTransitionManager() {}
 
   typedef nsTArray<RefPtr<mozilla::dom::CSSTransition>>
     OwningCSSTransitionPtrArray;