diff --git a/dom/media/MediaPromise.h b/dom/media/MediaPromise.h index ce20ca1247..ca8f19a6ba 100644 --- a/dom/media/MediaPromise.h +++ b/dom/media/MediaPromise.h @@ -42,12 +42,31 @@ template static FalseType TakesArgumentHelper(Ret (ThisType::*)()); template static FalseType TakesArgumentHelper(Ret (ThisType::*)() const); + +template +static Ret ReturnTypeHelper(Ret (ThisType::*)(ArgType)); +template +static Ret ReturnTypeHelper(Ret (ThisType::*)(ArgType) const); +template +static Ret ReturnTypeHelper(Ret (ThisType::*)()); +template +static Ret ReturnTypeHelper(Ret (ThisType::*)() const); + +template +struct ReturnType { + typedef decltype(detail::ReturnTypeHelper(DeclVal())) Type; +}; + } // namespace detail template struct TakesArgument { - typedef decltype(detail::TakesArgumentHelper(DeclVal())) Type; - static const bool value = Type::value; + static const bool value = decltype(detail::TakesArgumentHelper(DeclVal()))::value; +}; + +template +struct ReturnTypeIs { + static const bool value = IsConvertible::Type, TargetType>::value; }; /* @@ -259,17 +278,41 @@ protected: */ template - static typename EnableIf::value, void>::Type + static typename EnableIf>::value && + TakesArgument::value, + already_AddRefed>::Type InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue) { - ((*aThisVal).*aMethod)(aValue); + return ((*aThisVal).*aMethod)(aValue).forget(); } template - static typename EnableIf::value, void>::Type + static typename EnableIf::value && + TakesArgument::value, + already_AddRefed>::Type InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue) { - ((*aThisVal).*aMethod)(); + ((*aThisVal).*aMethod)(aValue); + return nullptr; + } + + template + static typename EnableIf>::value && + !TakesArgument::value, + already_AddRefed>::Type + InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue) + { + return ((*aThisVal).*aMethod)().forget(); + } + + template + static typename EnableIf::value && + !TakesArgument::value, + already_AddRefed>::Type + InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue) + { + ((*aThisVal).*aMethod)(); + return nullptr; } template @@ -297,10 +340,11 @@ protected: protected: virtual void DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override { + nsRefPtr completion; if (aValue.IsResolve()) { - InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aValue.ResolveValue()); + completion = InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aValue.ResolveValue()); } else { - InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aValue.RejectValue()); + completion = InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aValue.RejectValue()); } // Null out mThisVal after invoking the callback so that any references are @@ -351,10 +395,11 @@ protected: // classes with ::operator()), since it allows us to share code more easily. // We could fix this if need be, though it's quite easy to work around by // just capturing something. + nsRefPtr completion; if (aValue.IsResolve()) { - InvokeCallbackMethod(mResolveFunction.ptr(), &ResolveFunction::operator(), aValue.ResolveValue()); + completion = InvokeCallbackMethod(mResolveFunction.ptr(), &ResolveFunction::operator(), aValue.ResolveValue()); } else { - InvokeCallbackMethod(mRejectFunction.ptr(), &RejectFunction::operator(), aValue.RejectValue()); + completion = InvokeCallbackMethod(mRejectFunction.ptr(), &RejectFunction::operator(), aValue.RejectValue()); } // Destroy callbacks after invocation so that any references in closures are