dom/smil/nsSMILTimeContainer.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/smil/nsSMILTimeContainer.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,296 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef NS_SMILTIMECONTAINER_H_
    1.10 +#define NS_SMILTIMECONTAINER_H_
    1.11 +
    1.12 +#include "mozilla/dom/SVGAnimationElement.h"
    1.13 +#include "nscore.h"
    1.14 +#include "nsSMILTypes.h"
    1.15 +#include "nsTPriorityQueue.h"
    1.16 +#include "nsAutoPtr.h"
    1.17 +#include "nsSMILMilestone.h"
    1.18 +
    1.19 +class nsSMILTimeValue;
    1.20 +
    1.21 +//----------------------------------------------------------------------
    1.22 +// nsSMILTimeContainer
    1.23 +//
    1.24 +// Common base class for a time base that can be paused, resumed, and sampled.
    1.25 +//
    1.26 +class nsSMILTimeContainer
    1.27 +{
    1.28 +public:
    1.29 +  nsSMILTimeContainer();
    1.30 +  virtual ~nsSMILTimeContainer();
    1.31 +
    1.32 +  /*
    1.33 +   * Pause request types.
    1.34 +   */
    1.35 +  enum {
    1.36 +    PAUSE_BEGIN    =  1, // Paused because timeline has yet to begin.
    1.37 +    PAUSE_SCRIPT   =  2, // Paused by script.
    1.38 +    PAUSE_PAGEHIDE =  4, // Paused because our doc is hidden.
    1.39 +    PAUSE_USERPREF =  8, // Paused because animations are disabled in prefs.
    1.40 +    PAUSE_IMAGE    = 16  // Paused becuase we're in an image that's suspended.
    1.41 +  };
    1.42 +
    1.43 +  /*
    1.44 +   * Cause the time container to record its begin time.
    1.45 +   */
    1.46 +  void Begin();
    1.47 +
    1.48 +  /*
    1.49 +   * Pause this time container
    1.50 +   *
    1.51 +   * @param aType The source of the pause request. Successive calls to Pause
    1.52 +   * with the same aType will be ignored. The container will remain paused until
    1.53 +   * each call to Pause of a given aType has been matched by at least one call
    1.54 +   * to Resume with the same aType.
    1.55 +   */
    1.56 +  virtual void Pause(uint32_t aType);
    1.57 +
    1.58 +  /*
    1.59 +   * Resume this time container
    1.60 +   *
    1.61 +   * param @aType The source of the resume request. Clears the pause flag for
    1.62 +   * this particular type of pause request. When all pause flags have been
    1.63 +   * cleared the time container will be resumed.
    1.64 +   */
    1.65 +  virtual void Resume(uint32_t aType);
    1.66 +
    1.67 +  /**
    1.68 +   * Returns true if this time container is paused by the specified type.
    1.69 +   * Note that the time container may also be paused by other types; this method
    1.70 +   * does not test if aType is the exclusive pause source.
    1.71 +   *
    1.72 +   * @param @aType The pause source to test for.
    1.73 +   * @return true if this container is paused by aType.
    1.74 +   */
    1.75 +  bool IsPausedByType(uint32_t aType) const { return mPauseState & aType; }
    1.76 +
    1.77 +  /**
    1.78 +   * Returns true if this time container is paused.
    1.79 +   * Generally you should test for a specific type of pausing using
    1.80 +   * IsPausedByType.
    1.81 +   *
    1.82 +   * @return true if this container is paused, false otherwise.
    1.83 +   */
    1.84 +  bool IsPaused() const { return mPauseState != 0; }
    1.85 +
    1.86 +  /*
    1.87 +   * Return the time elapsed since this time container's begin time (expressed
    1.88 +   * in parent time) minus any accumulated offset from pausing.
    1.89 +   */
    1.90 +  nsSMILTime GetCurrentTime() const;
    1.91 +
    1.92 +  /*
    1.93 +   * Seek the document timeline to the specified time.
    1.94 +   *
    1.95 +   * @param aSeekTo The time to seek to, expressed in this time container's time
    1.96 +   * base (i.e. the same units as GetCurrentTime).
    1.97 +   */
    1.98 +  void SetCurrentTime(nsSMILTime aSeekTo);
    1.99 +
   1.100 +  /*
   1.101 +   * Return the current time for the parent time container if any.
   1.102 +   */
   1.103 +  virtual nsSMILTime GetParentTime() const;
   1.104 +
   1.105 +  /*
   1.106 +   * Convert container time to parent time.
   1.107 +   *
   1.108 +   * @param   aContainerTime The container time to convert.
   1.109 +   * @return  The equivalent parent time or indefinite if the container is
   1.110 +   *          paused and the time is in the future.
   1.111 +   */
   1.112 +  nsSMILTimeValue ContainerToParentTime(nsSMILTime aContainerTime) const;
   1.113 +
   1.114 +  /*
   1.115 +   * Convert from parent time to container time.
   1.116 +   *
   1.117 +   * @param   aParentTime The parent time to convert.
   1.118 +   * @return  The equivalent container time or indefinite if the container is
   1.119 +   *          paused and aParentTime is after the time when the pause began.
   1.120 +   */
   1.121 +  nsSMILTimeValue ParentToContainerTime(nsSMILTime aParentTime) const;
   1.122 +
   1.123 +  /*
   1.124 +   * If the container is paused, causes the pause time to be updated to the
   1.125 +   * current parent time. This should be called before updating
   1.126 +   * cross-container dependencies that will call ContainerToParentTime in order
   1.127 +   * to provide more intuitive results.
   1.128 +   */
   1.129 +  void SyncPauseTime();
   1.130 +
   1.131 +  /*
   1.132 +   * Updates the current time of this time container and calls DoSample to
   1.133 +   * perform any sample-operations.
   1.134 +   */
   1.135 +  void Sample();
   1.136 +
   1.137 +  /*
   1.138 +   * Return if this time container should be sampled or can be skipped.
   1.139 +   *
   1.140 +   * This is most useful as an optimisation for skipping time containers that
   1.141 +   * don't require a sample.
   1.142 +   */
   1.143 +  bool NeedsSample() const { return !mPauseState || mNeedsPauseSample; }
   1.144 +
   1.145 +  /*
   1.146 +   * Indicates if the elements of this time container need to be rewound.
   1.147 +   * This occurs during a backwards seek.
   1.148 +   */
   1.149 +  bool NeedsRewind() const { return mNeedsRewind; }
   1.150 +  void ClearNeedsRewind() { mNeedsRewind = false; }
   1.151 +
   1.152 +  /*
   1.153 +   * Indicates the time container is currently processing a SetCurrentTime
   1.154 +   * request and appropriate seek behaviour should be applied by child elements
   1.155 +   * (e.g. not firing time events).
   1.156 +   */
   1.157 +  bool IsSeeking() const { return mIsSeeking; }
   1.158 +  void MarkSeekFinished() { mIsSeeking = false; }
   1.159 +
   1.160 +  /*
   1.161 +   * Sets the parent time container.
   1.162 +   *
   1.163 +   * The callee still retains ownership of the time container.
   1.164 +   */
   1.165 +  nsresult SetParent(nsSMILTimeContainer* aParent);
   1.166 +
   1.167 +  /*
   1.168 +   * Registers an element for a sample at the given time.
   1.169 +   *
   1.170 +   * @param   aMilestone  The milestone to register in container time.
   1.171 +   * @param   aElement    The timebase element that needs a sample at
   1.172 +   *                      aMilestone.
   1.173 +   * @return  true if the element was successfully added, false otherwise.
   1.174 +   */
   1.175 +  bool AddMilestone(const nsSMILMilestone& aMilestone,
   1.176 +                    mozilla::dom::SVGAnimationElement& aElement);
   1.177 +
   1.178 +  /*
   1.179 +   * Resets the list of milestones.
   1.180 +   */
   1.181 +  void ClearMilestones();
   1.182 +
   1.183 +  /*
   1.184 +   * Returns the next significant transition from amongst the registered
   1.185 +   * milestones.
   1.186 +   *
   1.187 +   * @param[out] aNextMilestone The next milestone with time in parent time.
   1.188 +   *
   1.189 +   * @return true if there exists another milestone, false otherwise in
   1.190 +   * which case aNextMilestone will be unmodified.
   1.191 +   */
   1.192 +  bool GetNextMilestoneInParentTime(nsSMILMilestone& aNextMilestone) const;
   1.193 +
   1.194 +  typedef nsTArray<nsRefPtr<mozilla::dom::SVGAnimationElement> > AnimElemArray;
   1.195 +
   1.196 +  /*
   1.197 +   * Removes and returns the timebase elements from the start of the list of
   1.198 +   * timebase elements that match the given time.
   1.199 +   *
   1.200 +   * @param      aMilestone  The milestone time to match in parent time. This
   1.201 +   *                         must be <= GetNextMilestoneInParentTime.
   1.202 +   * @param[out] aMatchedElements The array to which matching elements will be
   1.203 +   *                              appended.
   1.204 +   * @return true if one or more elements match, false otherwise.
   1.205 +   */
   1.206 +  bool PopMilestoneElementsAtMilestone(const nsSMILMilestone& aMilestone,
   1.207 +                                         AnimElemArray& aMatchedElements);
   1.208 +
   1.209 +  // Cycle-collection support
   1.210 +  void Traverse(nsCycleCollectionTraversalCallback* aCallback);
   1.211 +  void Unlink();
   1.212 +
   1.213 +protected:
   1.214 +  /*
   1.215 +   * Per-sample operations to be performed whenever Sample() is called and
   1.216 +   * NeedsSample() is true. Called after updating mCurrentTime;
   1.217 +   */
   1.218 +  virtual void DoSample() { }
   1.219 +
   1.220 +  /*
   1.221 +   * Adding and removing child containers is not implemented in the base class
   1.222 +   * because not all subclasses need this.
   1.223 +   */
   1.224 +
   1.225 +  /*
   1.226 +   * Adds a child time container.
   1.227 +   */
   1.228 +  virtual nsresult AddChild(nsSMILTimeContainer& aChild)
   1.229 +  {
   1.230 +    return NS_ERROR_FAILURE;
   1.231 +  }
   1.232 +
   1.233 +  /*
   1.234 +   * Removes a child time container.
   1.235 +   */
   1.236 +  virtual void RemoveChild(nsSMILTimeContainer& aChild) { }
   1.237 +
   1.238 +  /*
   1.239 +   * Implementation helper to update the current time.
   1.240 +   */
   1.241 +  void UpdateCurrentTime();
   1.242 +
   1.243 +  /*
   1.244 +   * Implementation helper to notify timed elements with dependencies that the
   1.245 +   * container time has changed with respect to the document time.
   1.246 +   */
   1.247 +  void NotifyTimeChange();
   1.248 +
   1.249 +  // The parent time container, if any
   1.250 +  nsSMILTimeContainer* mParent;
   1.251 +
   1.252 +  // The current time established at the last call to Sample()
   1.253 +  nsSMILTime mCurrentTime;
   1.254 +
   1.255 +  // The number of milliseconds for which the container has been paused
   1.256 +  // (excluding the current pause interval if the container is currently
   1.257 +  // paused).
   1.258 +  //
   1.259 +  //  Current time = parent time - mParentOffset
   1.260 +  //
   1.261 +  nsSMILTime mParentOffset;
   1.262 +
   1.263 +  // The timestamp in parent time when the container was paused
   1.264 +  nsSMILTime mPauseStart;
   1.265 +
   1.266 +  // Whether or not a pause sample is required
   1.267 +  bool mNeedsPauseSample;
   1.268 +
   1.269 +  bool mNeedsRewind; // Backwards seek performed
   1.270 +  bool mIsSeeking; // Currently in the middle of a seek operation
   1.271 +
   1.272 +  // A bitfield of the pause state for all pause requests
   1.273 +  uint32_t mPauseState;
   1.274 +
   1.275 +  struct MilestoneEntry
   1.276 +  {
   1.277 +    MilestoneEntry(nsSMILMilestone aMilestone,
   1.278 +                   mozilla::dom::SVGAnimationElement& aElement)
   1.279 +      : mMilestone(aMilestone), mTimebase(&aElement)
   1.280 +    { }
   1.281 +
   1.282 +    bool operator<(const MilestoneEntry& aOther) const
   1.283 +    {
   1.284 +      return mMilestone < aOther.mMilestone;
   1.285 +    }
   1.286 +
   1.287 +    nsSMILMilestone mMilestone; // In container time.
   1.288 +    nsRefPtr<mozilla::dom::SVGAnimationElement> mTimebase;
   1.289 +  };
   1.290 +
   1.291 +  // Queue of elements with registered milestones. Used to update the model with
   1.292 +  // significant transitions that occur between two samples. Since timed element
   1.293 +  // re-register their milestones when they're sampled this is reset once we've
   1.294 +  // taken care of the milestones before the current sample time but before we
   1.295 +  // actually do the full sample.
   1.296 +  nsTPriorityQueue<MilestoneEntry> mMilestoneEntries;
   1.297 +};
   1.298 +
   1.299 +#endif // NS_SMILTIMECONTAINER_H_

mercurial