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/. */
7 #include "SMILInstanceTime.h"
9 #include "mozilla/AutoRestore.h"
10 #include "mozilla/SMILInterval.h"
11 #include "mozilla/SMILTimeValueSpec.h"
15 //----------------------------------------------------------------------
18 SMILInstanceTime::SMILInstanceTime(const SMILTimeValue
& aTime
,
19 SMILInstanceTimeSource aSource
,
20 SMILTimeValueSpec
* aCreator
,
21 SMILInterval
* aBaseInterval
)
25 mFixedEndpointRefCnt(0),
28 mBaseInterval(nullptr) // This will get set to aBaseInterval in a call to
29 // SetBaseInterval() at end of constructor
37 mFlags
= kDynamic
| kFromDOM
;
49 SetBaseInterval(aBaseInterval
);
52 SMILInstanceTime::~SMILInstanceTime() {
53 MOZ_ASSERT(!mBaseInterval
,
54 "Destroying instance time without first calling Unlink()");
55 MOZ_ASSERT(mFixedEndpointRefCnt
== 0,
56 "Destroying instance time that is still used as the fixed "
57 "endpoint of an interval");
60 void SMILInstanceTime::Unlink() {
61 RefPtr
<SMILInstanceTime
> deathGrip(this);
63 mBaseInterval
->RemoveDependentTime(*this);
64 mBaseInterval
= nullptr;
69 void SMILInstanceTime::HandleChangedInterval(
70 const SMILTimeContainer
* aSrcContainer
, bool aBeginObjectChanged
,
71 bool aEndObjectChanged
) {
72 // It's possible a sequence of notifications might cause our base interval to
73 // be updated and then deleted. Furthermore, the delete might happen whilst
74 // we're still in the queue to be notified of the change. In any case, if we
75 // don't have a base interval, just ignore the change.
76 if (!mBaseInterval
) return;
78 MOZ_ASSERT(mCreator
, "Base interval is set but creator is not.");
81 // Break the cycle here
87 mCreator
->DependsOnBegin() ? aBeginObjectChanged
: aEndObjectChanged
;
89 RefPtr
<SMILInstanceTime
> deathGrip(this);
90 mozilla::AutoRestore
<bool> setVisited(mVisited
);
93 mCreator
->HandleChangedInstanceTime(*GetBaseTime(), aSrcContainer
, *this,
97 void SMILInstanceTime::HandleDeletedInterval() {
98 MOZ_ASSERT(mBaseInterval
,
99 "Got call to HandleDeletedInterval on an independent instance "
101 MOZ_ASSERT(mCreator
, "Base interval is set but creator is not");
103 mBaseInterval
= nullptr;
104 mFlags
&= ~kMayUpdate
; // Can't update without a base interval
106 RefPtr
<SMILInstanceTime
> deathGrip(this);
107 mCreator
->HandleDeletedInstanceTime(*this);
111 void SMILInstanceTime::HandleFilteredInterval() {
112 MOZ_ASSERT(mBaseInterval
,
113 "Got call to HandleFilteredInterval on an independent instance "
116 mBaseInterval
= nullptr;
117 mFlags
&= ~kMayUpdate
; // Can't update without a base interval
121 bool SMILInstanceTime::ShouldPreserve() const {
122 return mFixedEndpointRefCnt
> 0 || (mFlags
& kWasDynamicEndpoint
);
125 void SMILInstanceTime::UnmarkShouldPreserve() {
126 mFlags
&= ~kWasDynamicEndpoint
;
129 void SMILInstanceTime::AddRefFixedEndpoint() {
130 MOZ_ASSERT(mFixedEndpointRefCnt
< UINT16_MAX
,
131 "Fixed endpoint reference count upper limit reached");
132 ++mFixedEndpointRefCnt
;
133 mFlags
&= ~kMayUpdate
; // Once fixed, always fixed
136 void SMILInstanceTime::ReleaseFixedEndpoint() {
137 MOZ_ASSERT(mFixedEndpointRefCnt
> 0, "Duplicate release");
138 --mFixedEndpointRefCnt
;
139 if (mFixedEndpointRefCnt
== 0 && IsDynamic()) {
140 mFlags
|= kWasDynamicEndpoint
;
144 bool SMILInstanceTime::IsDependentOn(const SMILInstanceTime
& aOther
) const {
145 if (mVisited
) return false;
147 const SMILInstanceTime
* myBaseTime
= GetBaseTime();
148 if (!myBaseTime
) return false;
150 if (myBaseTime
== &aOther
) return true;
152 mozilla::AutoRestore
<bool> setVisited(mVisited
);
154 return myBaseTime
->IsDependentOn(aOther
);
157 const SMILInstanceTime
* SMILInstanceTime::GetBaseTime() const {
158 if (!mBaseInterval
) {
162 MOZ_ASSERT(mCreator
, "Base interval is set but there is no creator.");
167 return mCreator
->DependsOnBegin() ? mBaseInterval
->Begin()
168 : mBaseInterval
->End();
171 void SMILInstanceTime::SetBaseInterval(SMILInterval
* aBaseInterval
) {
172 MOZ_ASSERT(!mBaseInterval
,
173 "Attempting to reassociate an instance time with a different "
178 "Attempting to create a dependent instance time without "
179 "reference to the creating SMILTimeValueSpec object.");
180 if (!mCreator
) return;
182 aBaseInterval
->AddDependentTime(*this);
185 mBaseInterval
= aBaseInterval
;
188 } // namespace mozilla