bug 1257718 introduce function-scope TimeOf() to simplify templated event time getter calls r?padenot draft
authorKarl Tomlinson <karlt+@karlt.net>
Fri, 17 Jun 2016 10:54:54 +1200
changeset 380504 8f1e9208dd2b7d3c50c0b2ddd0f4a3bfa1651f10
parent 380503 c04058c30fef01a90c35e76d98f397bbcad8768b
child 380505 8f14833543c1343c75739bc421c35cf581a64310
push id21234
push userktomlinson@mozilla.com
push dateWed, 22 Jun 2016 05:11:59 +0000
reviewerspadenot
bugs1257718
milestone50.0a1
bug 1257718 introduce function-scope TimeOf() to simplify templated event time getter calls r?padenot MozReview-Commit-ID: 7uKqlT2BpcS
dom/media/webaudio/AudioEventTimeline.cpp
--- a/dom/media/webaudio/AudioEventTimeline.cpp
+++ b/dom/media/webaudio/AudioEventTimeline.cpp
@@ -40,18 +40,22 @@ namespace mozilla {
 namespace dom {
 
 template <class ErrorResult> bool
 AudioEventTimeline::ValidateEvent(AudioTimelineEvent& aEvent,
                                   ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
+    return aEvent.template Time<double>();
+  };
+
   // Validate the event itself
-  if (!WebAudioUtils::IsTimeValid(aEvent.template Time<double>()) ||
+  if (!WebAudioUtils::IsTimeValid(TimeOf(aEvent)) ||
       !WebAudioUtils::IsTimeValid(aEvent.mTimeConstant)) {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return false;
   }
 
   if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
     if (!aEvent.mCurve || !aEvent.mCurveLength) {
       aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
@@ -78,48 +82,48 @@ AudioEventTimeline::ValidateEvent(AudioT
     return false;
   }
 
   // Make sure that non-curve events don't fall within the duration of a
   // curve event.
   for (unsigned i = 0; i < mEvents.Length(); ++i) {
     if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
         !(aEvent.mType == AudioTimelineEvent::SetValueCurve &&
-          aEvent.template Time<double>() == mEvents[i].template Time<double>()) &&
-        mEvents[i].template Time<double>() <= aEvent.template Time<double>() &&
-        (mEvents[i].template Time<double>() + mEvents[i].mDuration) >= aEvent.template Time<double>()) {
+          TimeOf(aEvent) == TimeOf(mEvents[i])) &&
+        TimeOf(mEvents[i]) <= TimeOf(aEvent) &&
+        TimeOf(mEvents[i]) + mEvents[i].mDuration >= TimeOf(aEvent)) {
       aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
       return false;
     }
   }
 
   // Make sure that curve events don't fall in a range which includes other
   // events.
   if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
     for (unsigned i = 0; i < mEvents.Length(); ++i) {
       // In case we have two curve at the same time
       if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
-          mEvents[i].template Time<double>() == aEvent.template Time<double>()) {
+          TimeOf(mEvents[i]) == TimeOf(aEvent)) {
         continue;
       }
-      if (mEvents[i].template Time<double>() > aEvent.template Time<double>() &&
-          mEvents[i].template Time<double>() < (aEvent.template Time<double>() + aEvent.mDuration)) {
+      if (TimeOf(mEvents[i]) > TimeOf(aEvent) &&
+          TimeOf(mEvents[i]) < TimeOf(aEvent) + aEvent.mDuration) {
         aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
         return false;
       }
     }
   }
 
   // Make sure that invalid values are not used for exponential curves
   if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) {
     if (aEvent.mValue <= 0.f) {
       aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
       return false;
     }
-    const AudioTimelineEvent* previousEvent = GetPreviousEvent(aEvent.template Time<double>());
+    const AudioTimelineEvent* previousEvent = GetPreviousEvent(TimeOf(aEvent));
     if (previousEvent) {
       if (previousEvent->mValue <= 0.f) {
         aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
         return false;
       }
     } else {
       if (mValue <= 0.f) {
         aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
@@ -136,73 +140,77 @@ AudioEventTimeline::ValidateEvent(AudioT
 // This method computes the AudioParam value at a given time based on the event timeline
 template<class TimeType> void
 AudioEventTimeline::GetValuesAtTimeHelper(TimeType aTime, float* aBuffer,
                                           const size_t aSize)
 {
   MOZ_ASSERT(aBuffer);
   MOZ_ASSERT(aSize);
 
+  auto TimeOf = [](const AudioTimelineEvent& aEvent) -> TimeType {
+    return aEvent.template Time<TimeType>();
+  };
+
   size_t eventIndex = 0;
   const AudioTimelineEvent* previous = nullptr;
   const AudioTimelineEvent* next = nullptr;
   bool bailOut = false;
 
   // Let's remove old events except the last one: we need it to calculate some curves.
   while (mEvents.Length() > 1 &&
-         aTime > mEvents[1].template Time<TimeType>()) {
+         aTime > TimeOf(mEvents[1])) {
     mEvents.RemoveElementAt(0);
   }
 
   for (size_t bufferIndex = 0; bufferIndex < aSize; ++bufferIndex, ++aTime) {
     for (; !bailOut && eventIndex < mEvents.Length(); ++eventIndex) {
 
 #ifdef DEBUG
       const AudioTimelineEvent* current = &mEvents[eventIndex];
       MOZ_ASSERT(current->mType == AudioTimelineEvent::SetValueAtTime ||
                  current->mType == AudioTimelineEvent::SetTarget ||
                  current->mType == AudioTimelineEvent::LinearRamp ||
                  current->mType == AudioTimelineEvent::ExponentialRamp ||
                  current->mType == AudioTimelineEvent::SetValueCurve);
 #endif
 
-      if (TimesEqual(aTime, mEvents[eventIndex].template Time<TimeType>())) {
+      if (TimesEqual(aTime, TimeOf(mEvents[eventIndex]))) {
         mLastComputedValue = mComputedValue;
         // Find the last event with the same time
         while (eventIndex < mEvents.Length() - 1 &&
-               TimesEqual(aTime, mEvents[eventIndex + 1].template Time<TimeType>())) {
+               TimesEqual(aTime, TimeOf(mEvents[eventIndex + 1]))) {
           ++eventIndex;
         }
         break;
       }
 
       previous = next;
       next = &mEvents[eventIndex];
-      if (aTime < mEvents[eventIndex].template Time<TimeType>()) {
+      if (aTime < TimeOf(mEvents[eventIndex])) {
         bailOut = true;
       }
     }
 
     if (!bailOut && eventIndex < mEvents.Length()) {
       // The time matches one of the events exactly.
-      MOZ_ASSERT(TimesEqual(aTime, mEvents[eventIndex].template Time<TimeType>()));
+      MOZ_ASSERT(TimesEqual(aTime, TimeOf(mEvents[eventIndex])));
 
       // SetTarget nodes can be handled no matter what their next node is (if they have one)
       if (mEvents[eventIndex].mType == AudioTimelineEvent::SetTarget) {
         // Follow the curve, without regard to the next event, starting at
         // the last value of the last event.
-        aBuffer[bufferIndex] = ExponentialApproach(mEvents[eventIndex].template Time<TimeType>(),
+        aBuffer[bufferIndex] = ExponentialApproach(TimeOf(mEvents[eventIndex]),
                                                 mLastComputedValue, mEvents[eventIndex].mValue,
                                                 mEvents[eventIndex].mTimeConstant, aTime);
         continue;
       }
 
       // SetValueCurve events can be handled no matter what their event node is (if they have one)
       if (mEvents[eventIndex].mType == AudioTimelineEvent::SetValueCurve) {
-        aBuffer[bufferIndex] = ExtractValueFromCurve(mEvents[eventIndex].template Time<TimeType>(),
+        aBuffer[bufferIndex] = ExtractValueFromCurve(TimeOf(mEvents[eventIndex]),
                                                   mEvents[eventIndex].mCurve,
                                                   mEvents[eventIndex].mCurveLength,
                                                   mEvents[eventIndex].mDuration, aTime);
         continue;
       }
 
       // For other event types
       aBuffer[bufferIndex] = mEvents[eventIndex].mValue;
@@ -229,42 +237,46 @@ AudioEventTimeline::GetValuesAtTimeHelpe
                                     const AudioTimelineEvent* aPrevious,
                                     const AudioTimelineEvent* aNext)
 {
   // If the requested time is before all of the existing events
   if (!aPrevious) {
      return mValue;
   }
 
+  auto TimeOf = [](const AudioTimelineEvent* aEvent) -> TimeType {
+    return aEvent->template Time<TimeType>();
+  };
+
   // SetTarget nodes can be handled no matter what their next node is (if
   // they have one)
   if (aPrevious->mType == AudioTimelineEvent::SetTarget) {
-    return ExponentialApproach(aPrevious->template Time<TimeType>(),
+    return ExponentialApproach(TimeOf(aPrevious),
                                mLastComputedValue, aPrevious->mValue,
                                aPrevious->mTimeConstant, aTime);
   }
 
   // SetValueCurve events can be handled no mattar what their next node is
   // (if they have one)
   if (aPrevious->mType == AudioTimelineEvent::SetValueCurve) {
-    return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
+    return ExtractValueFromCurve(TimeOf(aPrevious),
                                  aPrevious->mCurve, aPrevious->mCurveLength,
                                  aPrevious->mDuration, aTime);
   }
 
   // If the requested time is after all of the existing events
   if (!aNext) {
     switch (aPrevious->mType) {
       case AudioTimelineEvent::SetValueAtTime:
       case AudioTimelineEvent::LinearRamp:
       case AudioTimelineEvent::ExponentialRamp:
         // The value will be constant after the last event
         return aPrevious->mValue;
       case AudioTimelineEvent::SetValueCurve:
-        return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
+        return ExtractValueFromCurve(TimeOf(aPrevious),
                                      aPrevious->mCurve, aPrevious->mCurveLength,
                                      aPrevious->mDuration, aTime);
       case AudioTimelineEvent::SetTarget:
         MOZ_FALLTHROUGH_ASSERT("AudioTimelineEvent::SetTarget");
       case AudioTimelineEvent::SetValue:
       case AudioTimelineEvent::Cancel:
       case AudioTimelineEvent::Stream:
         MOZ_ASSERT(false, "Should have been handled earlier.");
@@ -272,25 +284,25 @@ AudioEventTimeline::GetValuesAtTimeHelpe
     MOZ_ASSERT(false, "unreached");
   }
 
   // Finally, handle the case where we have both a previous and a next event
 
   // First, handle the case where our range ends up in a ramp event
   switch (aNext->mType) {
   case AudioTimelineEvent::LinearRamp:
-    return LinearInterpolate(aPrevious->template Time<TimeType>(),
+    return LinearInterpolate(TimeOf(aPrevious),
                              aPrevious->mValue,
-                             aNext->template Time<TimeType>(),
+                             TimeOf(aNext),
                              aNext->mValue, aTime);
 
   case AudioTimelineEvent::ExponentialRamp:
-    return ExponentialInterpolate(aPrevious->template Time<TimeType>(),
+    return ExponentialInterpolate(TimeOf(aPrevious),
                                   aPrevious->mValue,
-                                  aNext->template Time<TimeType>(),
+                                  TimeOf(aNext),
                                   aNext->mValue, aTime);
 
   case AudioTimelineEvent::SetValueAtTime:
   case AudioTimelineEvent::SetTarget:
   case AudioTimelineEvent::SetValueCurve:
     break;
   case AudioTimelineEvent::SetValue:
   case AudioTimelineEvent::Cancel:
@@ -302,17 +314,17 @@ AudioEventTimeline::GetValuesAtTimeHelpe
   switch (aPrevious->mType) {
   case AudioTimelineEvent::SetValueAtTime:
   case AudioTimelineEvent::LinearRamp:
   case AudioTimelineEvent::ExponentialRamp:
     // If the next event type is neither linear or exponential ramp, the
     // value is constant.
     return aPrevious->mValue;
   case AudioTimelineEvent::SetValueCurve:
-    return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
+    return ExtractValueFromCurve(TimeOf(aPrevious),
                                  aPrevious->mCurve, aPrevious->mCurveLength,
                                  aPrevious->mDuration, aTime);
   case AudioTimelineEvent::SetTarget:
     MOZ_FALLTHROUGH_ASSERT("AudioTimelineEvent::SetTarget");
   case AudioTimelineEvent::SetValue:
   case AudioTimelineEvent::Cancel:
   case AudioTimelineEvent::Stream:
     MOZ_ASSERT(false, "Should have been handled earlier.");
@@ -331,35 +343,39 @@ AudioEventTimeline::GetValuesAtTimeHelpe
                                     const AudioTimelineEvent* aNext);
 
 const AudioTimelineEvent*
 AudioEventTimeline::GetPreviousEvent(double aTime) const
 {
   const AudioTimelineEvent* previous = nullptr;
   const AudioTimelineEvent* next = nullptr;
 
+  auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
+    return aEvent.template Time<double>();
+  };
+
   bool bailOut = false;
   for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) {
     switch (mEvents[i].mType) {
     case AudioTimelineEvent::SetValueAtTime:
     case AudioTimelineEvent::SetTarget:
     case AudioTimelineEvent::LinearRamp:
     case AudioTimelineEvent::ExponentialRamp:
     case AudioTimelineEvent::SetValueCurve:
-      if (aTime == mEvents[i].template Time<double>()) {
+      if (aTime == TimeOf(mEvents[i])) {
         // Find the last event with the same time
         do {
           ++i;
         } while (i < mEvents.Length() &&
-                 aTime == mEvents[i].template Time<double>());
+                 aTime == TimeOf(mEvents[i]));
         return &mEvents[i - 1];
       }
       previous = next;
       next = &mEvents[i];
-      if (aTime < mEvents[i].template Time<double>()) {
+      if (aTime < TimeOf(mEvents[i])) {
         bailOut = true;
       }
       break;
     default:
       MOZ_ASSERT(false, "unreached");
     }
   }
   // Handle the case where the time is past all of the events