SMILInterval.cpp (4852B)
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 #include "SMILInterval.h" 8 9 #include "mozilla/DebugOnly.h" 10 11 namespace mozilla { 12 13 SMILInterval::SMILInterval() : mBeginFixed(false), mEndFixed(false) {} 14 15 SMILInterval::SMILInterval(const SMILInterval& aOther) 16 : mBegin(aOther.mBegin), 17 mEnd(aOther.mEnd), 18 mBeginFixed(false), 19 mEndFixed(false) { 20 MOZ_ASSERT(aOther.mDependentTimes.IsEmpty(), 21 "Attempt to copy-construct an interval with dependent times; this " 22 "will lead to instance times being shared between intervals."); 23 24 // For the time being we don't allow intervals with fixed endpoints to be 25 // copied since we only ever copy-construct to establish a new current 26 // interval. If we ever need to copy historical intervals we may need to move 27 // the ReleaseFixedEndpoint calls from Unlink to the dtor. 28 MOZ_ASSERT(!aOther.mBeginFixed && !aOther.mEndFixed, 29 "Attempt to copy-construct an interval with fixed endpoints"); 30 } 31 32 SMILInterval::~SMILInterval() { 33 MOZ_ASSERT(mDependentTimes.IsEmpty(), 34 "Destroying interval without disassociating dependent instance " 35 "times. Unlink was not called"); 36 } 37 38 void SMILInterval::Unlink(bool aFiltered) { 39 for (int32_t i = mDependentTimes.Length() - 1; i >= 0; --i) { 40 if (aFiltered) { 41 mDependentTimes[i]->HandleFilteredInterval(); 42 } else { 43 mDependentTimes[i]->HandleDeletedInterval(); 44 } 45 } 46 mDependentTimes.Clear(); 47 if (mBegin && mBeginFixed) { 48 mBegin->ReleaseFixedEndpoint(); 49 } 50 mBegin = nullptr; 51 if (mEnd && mEndFixed) { 52 mEnd->ReleaseFixedEndpoint(); 53 } 54 mEnd = nullptr; 55 } 56 57 SMILInstanceTime* SMILInterval::Begin() { 58 MOZ_ASSERT(mBegin && mEnd, "Requesting Begin() on un-initialized interval."); 59 return mBegin; 60 } 61 62 SMILInstanceTime* SMILInterval::End() { 63 MOZ_ASSERT(mBegin && mEnd, "Requesting End() on un-initialized interval."); 64 return mEnd; 65 } 66 67 void SMILInterval::SetBegin(SMILInstanceTime& aBegin) { 68 MOZ_ASSERT(aBegin.Time().IsDefinite(), 69 "Attempt to set unresolved or indefinite begin time on interval"); 70 MOZ_ASSERT(!mBeginFixed, 71 "Attempt to set begin time but the begin point is fixed"); 72 // Check that we're not making an instance time dependent on itself. Such an 73 // arrangement does not make intuitive sense and should be detected when 74 // creating or updating intervals. 75 MOZ_ASSERT(!mBegin || aBegin.GetBaseTime() != mBegin, 76 "Attempt to make self-dependent instance time"); 77 78 mBegin = &aBegin; 79 } 80 81 void SMILInterval::SetEnd(SMILInstanceTime& aEnd) { 82 MOZ_ASSERT(!mEndFixed, "Attempt to set end time but the end point is fixed"); 83 // As with SetBegin, check we're not making an instance time dependent on 84 // itself. 85 MOZ_ASSERT(!mEnd || aEnd.GetBaseTime() != mEnd, 86 "Attempting to make self-dependent instance time"); 87 88 mEnd = &aEnd; 89 } 90 91 void SMILInterval::FixBegin() { 92 MOZ_ASSERT(mBegin && mEnd, "Fixing begin point on un-initialized interval"); 93 MOZ_ASSERT(!mBeginFixed, "Duplicate calls to FixBegin()"); 94 mBeginFixed = true; 95 mBegin->AddRefFixedEndpoint(); 96 } 97 98 void SMILInterval::FixEnd() { 99 MOZ_ASSERT(mBegin && mEnd, "Fixing end point on un-initialized interval"); 100 MOZ_ASSERT(mBeginFixed, 101 "Fixing the end of an interval without a fixed begin"); 102 MOZ_ASSERT(!mEndFixed, "Duplicate calls to FixEnd()"); 103 mEndFixed = true; 104 mEnd->AddRefFixedEndpoint(); 105 } 106 107 void SMILInterval::AddDependentTime(SMILInstanceTime& aTime) { 108 RefPtr<SMILInstanceTime>* inserted = 109 mDependentTimes.InsertElementSorted(&aTime); 110 if (!inserted) { 111 NS_WARNING("Insufficient memory to insert instance time."); 112 } 113 } 114 115 void SMILInterval::RemoveDependentTime(const SMILInstanceTime& aTime) { 116 DebugOnly<bool> found = mDependentTimes.RemoveElementSorted(&aTime); 117 MOZ_ASSERT(found, "Couldn't find instance time to delete."); 118 } 119 120 void SMILInterval::GetDependentTimes(InstanceTimeList& aTimes) { 121 aTimes = mDependentTimes.Clone(); 122 } 123 124 bool SMILInterval::IsDependencyChainLink() const { 125 if (!mBegin || !mEnd) 126 return false; // Not yet initialised so it can't be part of a chain 127 128 if (mDependentTimes.IsEmpty()) return false; // No dependents, chain end 129 130 // So we have dependents, but we're still only a link in the chain (as opposed 131 // to the end of the chain) if one of our endpoints is dependent on an 132 // interval other than ourselves. 133 return (mBegin->IsDependent() && mBegin->GetBaseInterval() != this) || 134 (mEnd->IsDependent() && mEnd->GetBaseInterval() != this); 135 } 136 137 } // namespace mozilla