dom/smil/nsSMILTimeContainer.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:7cdacdb20c48
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef NS_SMILTIMECONTAINER_H_
7 #define NS_SMILTIMECONTAINER_H_
8
9 #include "mozilla/dom/SVGAnimationElement.h"
10 #include "nscore.h"
11 #include "nsSMILTypes.h"
12 #include "nsTPriorityQueue.h"
13 #include "nsAutoPtr.h"
14 #include "nsSMILMilestone.h"
15
16 class nsSMILTimeValue;
17
18 //----------------------------------------------------------------------
19 // nsSMILTimeContainer
20 //
21 // Common base class for a time base that can be paused, resumed, and sampled.
22 //
23 class nsSMILTimeContainer
24 {
25 public:
26 nsSMILTimeContainer();
27 virtual ~nsSMILTimeContainer();
28
29 /*
30 * Pause request types.
31 */
32 enum {
33 PAUSE_BEGIN = 1, // Paused because timeline has yet to begin.
34 PAUSE_SCRIPT = 2, // Paused by script.
35 PAUSE_PAGEHIDE = 4, // Paused because our doc is hidden.
36 PAUSE_USERPREF = 8, // Paused because animations are disabled in prefs.
37 PAUSE_IMAGE = 16 // Paused becuase we're in an image that's suspended.
38 };
39
40 /*
41 * Cause the time container to record its begin time.
42 */
43 void Begin();
44
45 /*
46 * Pause this time container
47 *
48 * @param aType The source of the pause request. Successive calls to Pause
49 * with the same aType will be ignored. The container will remain paused until
50 * each call to Pause of a given aType has been matched by at least one call
51 * to Resume with the same aType.
52 */
53 virtual void Pause(uint32_t aType);
54
55 /*
56 * Resume this time container
57 *
58 * param @aType The source of the resume request. Clears the pause flag for
59 * this particular type of pause request. When all pause flags have been
60 * cleared the time container will be resumed.
61 */
62 virtual void Resume(uint32_t aType);
63
64 /**
65 * Returns true if this time container is paused by the specified type.
66 * Note that the time container may also be paused by other types; this method
67 * does not test if aType is the exclusive pause source.
68 *
69 * @param @aType The pause source to test for.
70 * @return true if this container is paused by aType.
71 */
72 bool IsPausedByType(uint32_t aType) const { return mPauseState & aType; }
73
74 /**
75 * Returns true if this time container is paused.
76 * Generally you should test for a specific type of pausing using
77 * IsPausedByType.
78 *
79 * @return true if this container is paused, false otherwise.
80 */
81 bool IsPaused() const { return mPauseState != 0; }
82
83 /*
84 * Return the time elapsed since this time container's begin time (expressed
85 * in parent time) minus any accumulated offset from pausing.
86 */
87 nsSMILTime GetCurrentTime() const;
88
89 /*
90 * Seek the document timeline to the specified time.
91 *
92 * @param aSeekTo The time to seek to, expressed in this time container's time
93 * base (i.e. the same units as GetCurrentTime).
94 */
95 void SetCurrentTime(nsSMILTime aSeekTo);
96
97 /*
98 * Return the current time for the parent time container if any.
99 */
100 virtual nsSMILTime GetParentTime() const;
101
102 /*
103 * Convert container time to parent time.
104 *
105 * @param aContainerTime The container time to convert.
106 * @return The equivalent parent time or indefinite if the container is
107 * paused and the time is in the future.
108 */
109 nsSMILTimeValue ContainerToParentTime(nsSMILTime aContainerTime) const;
110
111 /*
112 * Convert from parent time to container time.
113 *
114 * @param aParentTime The parent time to convert.
115 * @return The equivalent container time or indefinite if the container is
116 * paused and aParentTime is after the time when the pause began.
117 */
118 nsSMILTimeValue ParentToContainerTime(nsSMILTime aParentTime) const;
119
120 /*
121 * If the container is paused, causes the pause time to be updated to the
122 * current parent time. This should be called before updating
123 * cross-container dependencies that will call ContainerToParentTime in order
124 * to provide more intuitive results.
125 */
126 void SyncPauseTime();
127
128 /*
129 * Updates the current time of this time container and calls DoSample to
130 * perform any sample-operations.
131 */
132 void Sample();
133
134 /*
135 * Return if this time container should be sampled or can be skipped.
136 *
137 * This is most useful as an optimisation for skipping time containers that
138 * don't require a sample.
139 */
140 bool NeedsSample() const { return !mPauseState || mNeedsPauseSample; }
141
142 /*
143 * Indicates if the elements of this time container need to be rewound.
144 * This occurs during a backwards seek.
145 */
146 bool NeedsRewind() const { return mNeedsRewind; }
147 void ClearNeedsRewind() { mNeedsRewind = false; }
148
149 /*
150 * Indicates the time container is currently processing a SetCurrentTime
151 * request and appropriate seek behaviour should be applied by child elements
152 * (e.g. not firing time events).
153 */
154 bool IsSeeking() const { return mIsSeeking; }
155 void MarkSeekFinished() { mIsSeeking = false; }
156
157 /*
158 * Sets the parent time container.
159 *
160 * The callee still retains ownership of the time container.
161 */
162 nsresult SetParent(nsSMILTimeContainer* aParent);
163
164 /*
165 * Registers an element for a sample at the given time.
166 *
167 * @param aMilestone The milestone to register in container time.
168 * @param aElement The timebase element that needs a sample at
169 * aMilestone.
170 * @return true if the element was successfully added, false otherwise.
171 */
172 bool AddMilestone(const nsSMILMilestone& aMilestone,
173 mozilla::dom::SVGAnimationElement& aElement);
174
175 /*
176 * Resets the list of milestones.
177 */
178 void ClearMilestones();
179
180 /*
181 * Returns the next significant transition from amongst the registered
182 * milestones.
183 *
184 * @param[out] aNextMilestone The next milestone with time in parent time.
185 *
186 * @return true if there exists another milestone, false otherwise in
187 * which case aNextMilestone will be unmodified.
188 */
189 bool GetNextMilestoneInParentTime(nsSMILMilestone& aNextMilestone) const;
190
191 typedef nsTArray<nsRefPtr<mozilla::dom::SVGAnimationElement> > AnimElemArray;
192
193 /*
194 * Removes and returns the timebase elements from the start of the list of
195 * timebase elements that match the given time.
196 *
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
200 * appended.
201 * @return true if one or more elements match, false otherwise.
202 */
203 bool PopMilestoneElementsAtMilestone(const nsSMILMilestone& aMilestone,
204 AnimElemArray& aMatchedElements);
205
206 // Cycle-collection support
207 void Traverse(nsCycleCollectionTraversalCallback* aCallback);
208 void Unlink();
209
210 protected:
211 /*
212 * Per-sample operations to be performed whenever Sample() is called and
213 * NeedsSample() is true. Called after updating mCurrentTime;
214 */
215 virtual void DoSample() { }
216
217 /*
218 * Adding and removing child containers is not implemented in the base class
219 * because not all subclasses need this.
220 */
221
222 /*
223 * Adds a child time container.
224 */
225 virtual nsresult AddChild(nsSMILTimeContainer& aChild)
226 {
227 return NS_ERROR_FAILURE;
228 }
229
230 /*
231 * Removes a child time container.
232 */
233 virtual void RemoveChild(nsSMILTimeContainer& aChild) { }
234
235 /*
236 * Implementation helper to update the current time.
237 */
238 void UpdateCurrentTime();
239
240 /*
241 * Implementation helper to notify timed elements with dependencies that the
242 * container time has changed with respect to the document time.
243 */
244 void NotifyTimeChange();
245
246 // The parent time container, if any
247 nsSMILTimeContainer* mParent;
248
249 // The current time established at the last call to Sample()
250 nsSMILTime mCurrentTime;
251
252 // The number of milliseconds for which the container has been paused
253 // (excluding the current pause interval if the container is currently
254 // paused).
255 //
256 // Current time = parent time - mParentOffset
257 //
258 nsSMILTime mParentOffset;
259
260 // The timestamp in parent time when the container was paused
261 nsSMILTime mPauseStart;
262
263 // Whether or not a pause sample is required
264 bool mNeedsPauseSample;
265
266 bool mNeedsRewind; // Backwards seek performed
267 bool mIsSeeking; // Currently in the middle of a seek operation
268
269 // A bitfield of the pause state for all pause requests
270 uint32_t mPauseState;
271
272 struct MilestoneEntry
273 {
274 MilestoneEntry(nsSMILMilestone aMilestone,
275 mozilla::dom::SVGAnimationElement& aElement)
276 : mMilestone(aMilestone), mTimebase(&aElement)
277 { }
278
279 bool operator<(const MilestoneEntry& aOther) const
280 {
281 return mMilestone < aOther.mMilestone;
282 }
283
284 nsSMILMilestone mMilestone; // In container time.
285 nsRefPtr<mozilla::dom::SVGAnimationElement> mTimebase;
286 };
287
288 // Queue of elements with registered milestones. Used to update the model with
289 // significant transitions that occur between two samples. Since timed element
290 // re-register their milestones when they're sampled this is reset once we've
291 // taken care of the milestones before the current sample time but before we
292 // actually do the full sample.
293 nsTPriorityQueue<MilestoneEntry> mMilestoneEntries;
294 };
295
296 #endif // NS_SMILTIMECONTAINER_H_

mercurial