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_