Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/smil/nsSMILTimeContainer.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef NS_SMILTIMECONTAINER_H_
8
#define NS_SMILTIMECONTAINER_H_
9
10
#include "mozilla/dom/SVGAnimationElement.h"
11
#include "nscore.h"
12
#include "nsSMILTypes.h"
13
#include "nsTPriorityQueue.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
0
  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
0
  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
0
  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
0
  bool NeedsRewind() const { return mNeedsRewind; }
147
0
  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
0
  bool IsSeeking() const { return mIsSeeking; }
155
0
  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<RefPtr<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
0
  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
0
  {
227
0
    return NS_ERROR_FAILURE;
228
0
  }
229
230
  /*
231
   * Removes a child time container.
232
   */
233
0
  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
#ifdef DEBUG
270
  bool mHoldingEntries; // True if there's a raw pointer to mMilestoneEntries
271
                        // on the stack.
272
#endif
273
274
  // A bitfield of the pause state for all pause requests
275
  uint32_t mPauseState;
276
277
  struct MilestoneEntry
278
  {
279
    MilestoneEntry(const nsSMILMilestone& aMilestone,
280
                   mozilla::dom::SVGAnimationElement& aElement)
281
      : mMilestone(aMilestone), mTimebase(&aElement)
282
0
    { }
283
284
    bool operator<(const MilestoneEntry& aOther) const
285
0
    {
286
0
      return mMilestone < aOther.mMilestone;
287
0
    }
288
289
    nsSMILMilestone mMilestone; // In container time.
290
    RefPtr<mozilla::dom::SVGAnimationElement> mTimebase;
291
  };
292
293
  // Queue of elements with registered milestones. Used to update the model with
294
  // significant transitions that occur between two samples. Since timed element
295
  // re-register their milestones when they're sampled this is reset once we've
296
  // taken care of the milestones before the current sample time but before we
297
  // actually do the full sample.
298
  nsTPriorityQueue<MilestoneEntry> mMilestoneEntries;
299
};
300
301
#endif // NS_SMILTIMECONTAINER_H_