tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SMILTimeContainer.h (9842B)


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