1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DOM_SMIL_SMILTIMECONTAINER_H_
8 #define DOM_SMIL_SMILTIMECONTAINER_H_
10 #include "mozilla/dom/SVGAnimationElement.h"
11 #include "mozilla/SMILMilestone.h"
12 #include "mozilla/SMILTypes.h"
14 #include "nsTPriorityQueue.h"
20 //----------------------------------------------------------------------
23 // Common base class for a time base that can be paused, resumed, and sampled.
25 class SMILTimeContainer
{
28 virtual ~SMILTimeContainer();
31 * Pause request types.
34 PAUSE_BEGIN
= 1, // Paused because timeline has yet to begin.
35 PAUSE_SCRIPT
= 2, // Paused by script.
36 PAUSE_PAGEHIDE
= 4, // Paused because our doc is hidden.
37 PAUSE_USERPREF
= 8, // Paused because animations are disabled in prefs.
38 PAUSE_IMAGE
= 16 // Paused becuase we're in an image that's suspended.
42 * Cause the time container to record its begin time.
47 * Pause this time container
49 * @param aType The source of the pause request. Successive calls to Pause
50 * with the same aType will be ignored. The container will remain paused until
51 * each call to Pause of a given aType has been matched by at least one call
52 * to Resume with the same aType.
54 virtual void Pause(uint32_t aType
);
57 * Resume this time container
59 * param @aType The source of the resume request. Clears the pause flag for
60 * this particular type of pause request. When all pause flags have been
61 * cleared the time container will be resumed.
63 virtual void Resume(uint32_t aType
);
66 * Returns true if this time container is paused by the specified type.
67 * Note that the time container may also be paused by other types; this method
68 * does not test if aType is the exclusive pause source.
70 * @param @aType The pause source to test for.
71 * @return true if this container is paused by aType.
73 bool IsPausedByType(uint32_t aType
) const { return mPauseState
& aType
; }
76 * Returns true if this time container is paused.
77 * Generally you should test for a specific type of pausing using
80 * @return true if this container is paused, false otherwise.
82 bool IsPaused() const { return mPauseState
!= 0; }
85 * Return the time elapsed since this time container's begin time (expressed
86 * in parent time) minus any accumulated offset from pausing.
88 SMILTime
GetCurrentTimeAsSMILTime() const;
91 * Seek the document timeline to the specified time.
93 * @param aSeekTo The time to seek to, expressed in this time container's time
94 * base (i.e. the same units as GetCurrentTime).
96 void SetCurrentTime(SMILTime aSeekTo
);
99 * Return the current time for the parent time container if any.
101 virtual SMILTime
GetParentTime() const;
104 * Convert container time to parent time.
106 * @param aContainerTime The container time to convert.
107 * @return The equivalent parent time or indefinite if the container is
108 * paused and the time is in the future.
110 SMILTimeValue
ContainerToParentTime(SMILTime aContainerTime
) const;
113 * Convert from parent time to container time.
115 * @param aParentTime The parent time to convert.
116 * @return The equivalent container time or indefinite if the container is
117 * paused and aParentTime is after the time when the pause began.
119 SMILTimeValue
ParentToContainerTime(SMILTime aParentTime
) const;
122 * If the container is paused, causes the pause time to be updated to the
123 * current parent time. This should be called before updating
124 * cross-container dependencies that will call ContainerToParentTime in order
125 * to provide more intuitive results.
127 void SyncPauseTime();
130 * Updates the current time of this time container and calls DoSample to
131 * perform any sample-operations.
136 * Return if this time container should be sampled or can be skipped.
138 * This is most useful as an optimisation for skipping time containers that
139 * don't require a sample.
141 bool NeedsSample() const { return !mPauseState
|| mNeedsPauseSample
; }
144 * Indicates if the elements of this time container need to be rewound.
145 * This occurs during a backwards seek.
147 bool NeedsRewind() const { return mNeedsRewind
; }
148 void ClearNeedsRewind() { mNeedsRewind
= false; }
151 * Indicates the time container is currently processing a SetCurrentTime
152 * request and appropriate seek behaviour should be applied by child elements
153 * (e.g. not firing time events).
155 bool IsSeeking() const { return mIsSeeking
; }
156 void MarkSeekFinished() { mIsSeeking
= false; }
159 * Sets the parent time container.
161 * The callee still retains ownership of the time container.
163 nsresult
SetParent(SMILTimeContainer
* aParent
);
166 * Registers an element for a sample at the given time.
168 * @param aMilestone The milestone to register in container time.
169 * @param aElement The timebase element that needs a sample at
172 void AddMilestone(const SMILMilestone
& aMilestone
,
173 mozilla::dom::SVGAnimationElement
& aElement
);
176 * Resets the list of milestones.
178 void ClearMilestones();
181 * Returns the next significant transition from amongst the registered
184 * @param[out] aNextMilestone The next milestone with time in parent time.
186 * @return true if there exists another milestone, false otherwise in
187 * which case aNextMilestone will be unmodified.
189 bool GetNextMilestoneInParentTime(SMILMilestone
& aNextMilestone
) const;
191 using AnimElemArray
= nsTArray
<RefPtr
<dom::SVGAnimationElement
>>;
194 * Removes and returns the timebase elements from the start of the list of
195 * timebase elements that match the given time.
197 * @param aMilestone The milestone time to match in parent time. This
198 * must be <= GetNextMilestoneInParentTime.
199 * @param[out] aMatchedElements The array to which matching elements will be
201 * @return true if one or more elements match, false otherwise.
203 bool PopMilestoneElementsAtMilestone(const SMILMilestone
& aMilestone
,
204 AnimElemArray
& aMatchedElements
);
206 // Cycle-collection support
207 void Traverse(nsCycleCollectionTraversalCallback
* aCallback
);
212 * Per-sample operations to be performed whenever Sample() is called and
213 * NeedsSample() is true. Called after updating mCurrentTime;
215 virtual void DoSample() {}
218 * Adding and removing child containers is not implemented in the base class
219 * because not all subclasses need this.
223 * Adds a child time container.
225 virtual nsresult
AddChild(SMILTimeContainer
& aChild
) {
226 return NS_ERROR_FAILURE
;
230 * Removes a child time container.
232 virtual void RemoveChild(SMILTimeContainer
& aChild
) {}
235 * Implementation helper to update the current time.
237 void UpdateCurrentTime();
240 * Implementation helper to notify timed elements with dependencies that the
241 * container time has changed with respect to the document time.
243 void NotifyTimeChange();
245 // The parent time container, if any
246 SMILTimeContainer
* mParent
;
248 // The current time established at the last call to Sample()
249 SMILTime mCurrentTime
;
251 // The number of milliseconds for which the container has been paused
252 // (excluding the current pause interval if the container is currently
255 // Current time = parent time - mParentOffset
257 SMILTime mParentOffset
;
259 // The timestamp in parent time when the container was paused
260 SMILTime mPauseStart
;
262 // Whether or not a pause sample is required
263 bool mNeedsPauseSample
;
265 bool mNeedsRewind
; // Backwards seek performed
266 bool mIsSeeking
; // Currently in the middle of a seek operation
269 bool mHoldingEntries
; // True if there's a raw pointer to mMilestoneEntries
273 // A bitfield of the pause state for all pause requests
274 uint32_t mPauseState
;
276 struct MilestoneEntry
{
277 MilestoneEntry(const SMILMilestone
& aMilestone
,
278 mozilla::dom::SVGAnimationElement
& aElement
)
279 : mMilestone(aMilestone
), mTimebase(&aElement
) {}
281 bool operator<(const MilestoneEntry
& aOther
) const {
282 return mMilestone
< aOther
.mMilestone
;
285 SMILMilestone mMilestone
; // In container time.
286 RefPtr
<mozilla::dom::SVGAnimationElement
> mTimebase
;
289 // Queue of elements with registered milestones. Used to update the model with
290 // significant transitions that occur between two samples. Since timed element
291 // re-register their milestones when they're sampled this is reset once we've
292 // taken care of the milestones before the current sample time but before we
293 // actually do the full sample.
294 nsTPriorityQueue
<MilestoneEntry
> mMilestoneEntries
;
297 } // namespace mozilla
299 #endif // DOM_SMIL_SMILTIMECONTAINER_H_