1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is the Mozilla SMIL module.
16 : *
17 : * The Initial Developer of the Original Code is Brian Birtles.
18 : * Portions created by the Initial Developer are Copyright (C) 2009
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Brian Birtles <birtles@gmail.com>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "nsSMILInterval.h"
39 :
40 0 : nsSMILInterval::nsSMILInterval()
41 : :
42 : mBeginFixed(false),
43 0 : mEndFixed(false)
44 : {
45 0 : }
46 :
47 0 : nsSMILInterval::nsSMILInterval(const nsSMILInterval& aOther)
48 : :
49 : mBegin(aOther.mBegin),
50 : mEnd(aOther.mEnd),
51 : mBeginFixed(false),
52 0 : mEndFixed(false)
53 : {
54 0 : NS_ABORT_IF_FALSE(aOther.mDependentTimes.IsEmpty(),
55 : "Attempting to copy-construct an interval with dependent times, "
56 : "this will lead to instance times being shared between intervals.");
57 :
58 : // For the time being we don't allow intervals with fixed endpoints to be
59 : // copied since we only ever copy-construct to establish a new current
60 : // interval. If we ever need to copy historical intervals we may need to move
61 : // the ReleaseFixedEndpoint calls from Unlink to the dtor.
62 0 : NS_ABORT_IF_FALSE(!aOther.mBeginFixed && !aOther.mEndFixed,
63 : "Attempting to copy-construct an interval with fixed endpoints");
64 0 : }
65 :
66 0 : nsSMILInterval::~nsSMILInterval()
67 : {
68 0 : NS_ABORT_IF_FALSE(mDependentTimes.IsEmpty(),
69 : "Destroying interval without disassociating dependent instance times. "
70 : "Unlink was not called");
71 0 : }
72 :
73 : void
74 0 : nsSMILInterval::Unlink(bool aFiltered)
75 : {
76 0 : for (PRInt32 i = mDependentTimes.Length() - 1; i >= 0; --i) {
77 0 : if (aFiltered) {
78 0 : mDependentTimes[i]->HandleFilteredInterval();
79 : } else {
80 0 : mDependentTimes[i]->HandleDeletedInterval();
81 : }
82 : }
83 0 : mDependentTimes.Clear();
84 0 : if (mBegin && mBeginFixed) {
85 0 : mBegin->ReleaseFixedEndpoint();
86 : }
87 0 : mBegin = nsnull;
88 0 : if (mEnd && mEndFixed) {
89 0 : mEnd->ReleaseFixedEndpoint();
90 : }
91 0 : mEnd = nsnull;
92 0 : }
93 :
94 : nsSMILInstanceTime*
95 0 : nsSMILInterval::Begin()
96 : {
97 0 : NS_ABORT_IF_FALSE(mBegin && mEnd,
98 : "Requesting Begin() on un-initialized interval.");
99 0 : return mBegin;
100 : }
101 :
102 : nsSMILInstanceTime*
103 0 : nsSMILInterval::End()
104 : {
105 0 : NS_ABORT_IF_FALSE(mBegin && mEnd,
106 : "Requesting End() on un-initialized interval.");
107 0 : return mEnd;
108 : }
109 :
110 : void
111 0 : nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin)
112 : {
113 0 : NS_ABORT_IF_FALSE(aBegin.Time().IsDefinite(),
114 : "Attempting to set unresolved or indefinite begin time on interval");
115 0 : NS_ABORT_IF_FALSE(!mBeginFixed,
116 : "Attempting to set begin time but the begin point is fixed");
117 : // Check that we're not making an instance time dependent on itself. Such an
118 : // arrangement does not make intuitive sense and should be detected when
119 : // creating or updating intervals.
120 0 : NS_ABORT_IF_FALSE(!mBegin || aBegin.GetBaseTime() != mBegin,
121 : "Attempting to make self-dependent instance time");
122 :
123 0 : mBegin = &aBegin;
124 0 : }
125 :
126 : void
127 0 : nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd)
128 : {
129 0 : NS_ABORT_IF_FALSE(!mEndFixed,
130 : "Attempting to set end time but the end point is fixed");
131 : // As with SetBegin, check we're not making an instance time dependent on
132 : // itself.
133 0 : NS_ABORT_IF_FALSE(!mEnd || aEnd.GetBaseTime() != mEnd,
134 : "Attempting to make self-dependent instance time");
135 :
136 0 : mEnd = &aEnd;
137 0 : }
138 :
139 : void
140 0 : nsSMILInterval::FixBegin()
141 : {
142 0 : NS_ABORT_IF_FALSE(mBegin && mEnd,
143 : "Fixing begin point on un-initialized interval");
144 0 : NS_ABORT_IF_FALSE(!mBeginFixed, "Duplicate calls to FixBegin()");
145 0 : mBeginFixed = true;
146 0 : mBegin->AddRefFixedEndpoint();
147 0 : }
148 :
149 : void
150 0 : nsSMILInterval::FixEnd()
151 : {
152 0 : NS_ABORT_IF_FALSE(mBegin && mEnd,
153 : "Fixing end point on un-initialized interval");
154 0 : NS_ABORT_IF_FALSE(mBeginFixed,
155 : "Fixing the end of an interval without a fixed begin");
156 0 : NS_ABORT_IF_FALSE(!mEndFixed, "Duplicate calls to FixEnd()");
157 0 : mEndFixed = true;
158 0 : mEnd->AddRefFixedEndpoint();
159 0 : }
160 :
161 : void
162 0 : nsSMILInterval::AddDependentTime(nsSMILInstanceTime& aTime)
163 : {
164 : nsRefPtr<nsSMILInstanceTime>* inserted =
165 0 : mDependentTimes.InsertElementSorted(&aTime);
166 0 : if (!inserted) {
167 0 : NS_WARNING("Insufficient memory to insert instance time.");
168 : }
169 0 : }
170 :
171 : void
172 0 : nsSMILInterval::RemoveDependentTime(const nsSMILInstanceTime& aTime)
173 : {
174 : #ifdef DEBUG
175 : bool found =
176 : #endif
177 0 : mDependentTimes.RemoveElementSorted(&aTime);
178 0 : NS_ABORT_IF_FALSE(found, "Couldn't find instance time to delete.");
179 0 : }
180 :
181 : void
182 0 : nsSMILInterval::GetDependentTimes(InstanceTimeList& aTimes)
183 : {
184 0 : aTimes = mDependentTimes;
185 0 : }
186 :
187 : bool
188 0 : nsSMILInterval::IsDependencyChainLink() const
189 : {
190 0 : if (!mBegin || !mEnd)
191 0 : return false; // Not yet initialised so it can't be part of a chain
192 :
193 0 : if (mDependentTimes.IsEmpty())
194 0 : return false; // No dependents, chain end
195 :
196 : // So we have dependents, but we're still only a link in the chain (as opposed
197 : // to the end of the chain) if one of our endpoints is dependent on an
198 : // interval other than ourselves.
199 0 : return (mBegin->IsDependent() && mBegin->GetBaseInterval() != this) ||
200 0 : (mEnd->IsDependent() && mEnd->GetBaseInterval() != this);
201 : }
|