| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #ifndef CallbackPromiseAdapter_h | 31 #ifndef CallbackPromiseAdapter_h |
| 32 #define CallbackPromiseAdapter_h | 32 #define CallbackPromiseAdapter_h |
| 33 | 33 |
| 34 #include "bindings/core/v8/ScriptPromiseResolver.h" | 34 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 35 #include "public/platform/WebCallbacks.h" | 35 #include "public/platform/WebCallbacks.h" |
| 36 #include "public/platform/WebPassOwnPtr.h" | 36 #include "public/platform/WebPassOwnPtr.h" |
| 37 #include "wtf/OwnPtr.h" | 37 #include "wtf/OwnPtr.h" |
| 38 #include "wtf/PassOwnPtr.h" | 38 #include "wtf/PassOwnPtr.h" |
| 39 #include "wtf/TypeTraits.h" |
| 39 | 40 |
| 40 namespace blink { | 41 namespace blink { |
| 41 | 42 |
| 42 class CallbackPromiseAdapterBase { | 43 // This template is placed outside of CallbackPromiseAdapterInternal because |
| 43 public: | 44 // explicit specialization is forbidden in a class scope. |
| 45 template <typename T> |
| 46 struct CallbackPromiseAdapterTrivialWebTypeHolder { |
| 47 using WebType = T; |
| 48 // TODO(yhirano): Use universal reference and std::forward. |
| 49 static T take(ScriptPromiseResolver*, const T& x) { return x; } |
| 50 }; |
| 51 template <> |
| 52 struct CallbackPromiseAdapterTrivialWebTypeHolder<void> { |
| 53 using WebType = void; |
| 54 }; |
| 55 |
| 56 class CallbackPromiseAdapterInternal { |
| 57 private: |
| 58 template <typename T> static T webTypeHolderMatcher(typename WTF::RemoveRefe
rence<typename T::WebType>::Type*); |
| 59 template <typename T> static CallbackPromiseAdapterTrivialWebTypeHolder<T> w
ebTypeHolderMatcher(...); |
| 60 template <typename T> using WebTypeHolder = decltype(webTypeHolderMatcher<T>
(nullptr)); |
| 61 |
| 62 // TODO(yhirano): Use scoped_ptr. |
| 44 template <typename T> | 63 template <typename T> |
| 45 struct PassTypeImpl { | 64 struct PassTypeImpl { |
| 46 using Type = T; | 65 using Type = T; |
| 47 }; | 66 }; |
| 48 template <typename T> | 67 template <typename T> |
| 49 struct PassTypeImpl<OwnPtr<T>> { | 68 struct PassTypeImpl<OwnPtr<T>> { |
| 50 using Type = PassOwnPtr<T>; | 69 using Type = PassOwnPtr<T>; |
| 51 }; | 70 }; |
| 52 | |
| 53 template <typename T> | 71 template <typename T> |
| 54 struct WebPassTypeImpl { | 72 struct WebPassTypeImpl { |
| 55 using Type = T; | 73 using Type = T; |
| 56 }; | 74 }; |
| 57 template <typename T> | 75 template <typename T> |
| 58 struct WebPassTypeImpl<OwnPtr<T>> { | 76 struct WebPassTypeImpl<OwnPtr<T>> { |
| 59 using Type = WebPassOwnPtr<T>; | 77 using Type = WebPassOwnPtr<T>; |
| 60 }; | 78 }; |
| 61 | 79 template <typename T> using PassType = typename PassTypeImpl<T>::Type; |
| 62 template <typename T> | 80 template <typename T> using WebPassType = typename WebPassTypeImpl<T>::Type; |
| 63 using PassType = typename PassTypeImpl<T>::Type; | |
| 64 template <typename T> | |
| 65 using WebPassType = typename WebPassTypeImpl<T>::Type; | |
| 66 | 81 |
| 67 // TODO(yhirano): Use universal reference and std::forward. | 82 // TODO(yhirano): Use universal reference and std::forward. |
| 68 // https://chromium-cpp.appspot.com/ | 83 template <typename T> static T& adopt(T& x) { return x; } |
| 69 template <typename T> | 84 template <typename T> static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { retu
rn x.release(); } |
| 70 static T& adopt(T& x) { return x; } | |
| 71 template <typename T> | |
| 72 static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { return x.release(); } | |
| 73 | 85 |
| 74 // TODO(yhirano): Use rvalue reference and std::move. | 86 // TODO(yhirano): Use rvalue reference and std::move. |
| 75 // https://chromium-cpp.appspot.com/ | 87 template <typename T> static PassType<T> pass(T& x) { return x; } |
| 88 template <typename T> static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.rel
ease(); } |
| 89 |
| 90 template <typename S, typename T> |
| 91 class Base : public WebCallbacks<WebPassType<typename S::WebType>, WebPassTy
pe<typename T::WebType>> { |
| 92 public: |
| 93 explicit Base(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) :
m_resolver(resolver) {} |
| 94 ScriptPromiseResolver* resolver() { return m_resolver.get(); } |
| 95 |
| 96 private: |
| 97 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; |
| 98 }; |
| 99 |
| 100 template <typename S, typename T> |
| 101 class OnSuccess : public Base<S, T> { |
| 102 public: |
| 103 explicit OnSuccess(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve
r) : Base<S, T>(resolver) {} |
| 104 void onSuccess(WebPassType<typename S::WebType> r) override |
| 105 { |
| 106 typename S::WebType result(adopt(r)); |
| 107 ScriptPromiseResolver* resolver = this->resolver(); |
| 108 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 109 return; |
| 110 resolver->resolve(S::take(resolver, pass(result))); |
| 111 } |
| 112 }; |
| 76 template <typename T> | 113 template <typename T> |
| 77 static PassType<T> pass(T& x) { return x; } | 114 class OnSuccess<WebTypeHolder<void>, T> : public Base<WebTypeHolder<void>, T
> { |
| 78 template <typename T> | 115 public: |
| 79 static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.release(); } | 116 explicit OnSuccess(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve
r) : Base<WebTypeHolder<void>, T>(resolver) {} |
| 117 void onSuccess() override |
| 118 { |
| 119 ScriptPromiseResolver* resolver = this->resolver(); |
| 120 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 121 return; |
| 122 resolver->resolve(); |
| 123 } |
| 124 }; |
| 125 template <typename S, typename T> |
| 126 class OnError : public OnSuccess<S, T> { |
| 127 public: |
| 128 explicit OnError(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
: OnSuccess<S, T>(resolver) {} |
| 129 void onError(WebPassType<typename T::WebType> e) override |
| 130 { |
| 131 typename T::WebType result(adopt(e)); |
| 132 ScriptPromiseResolver* resolver = this->resolver(); |
| 133 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 134 return; |
| 135 resolver->reject(T::take(resolver, pass(result))); |
| 136 } |
| 137 }; |
| 138 template <typename S> |
| 139 class OnError<S, WebTypeHolder<void>> : public OnSuccess<S, WebTypeHolder<vo
id>> { |
| 140 public: |
| 141 explicit OnError(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
: OnSuccess<S, WebTypeHolder<void>>(resolver) {} |
| 142 void onError() override |
| 143 { |
| 144 ScriptPromiseResolver* resolver = this->resolver(); |
| 145 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 146 return; |
| 147 resolver->reject(); |
| 148 } |
| 149 }; |
| 150 |
| 151 public: |
| 152 template <typename S, typename T> |
| 153 class CallbackPromiseAdapter final : public OnError<WebTypeHolder<S>, WebTyp
eHolder<T>> { |
| 154 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); |
| 155 public: |
| 156 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseReso
lver> resolver) : OnError<WebTypeHolder<S>, WebTypeHolder<T>>(resolver) {} |
| 157 }; |
| 80 }; | 158 }; |
| 81 | 159 |
| 82 | 160 // CallbackPromiseAdapter is a WebCallbacks subclass and resolves / rejects the |
| 83 // TODO(yhirano): Add comments. | 161 // stored resolver when onSuccess / onError is called, respectively. |
| 84 template<typename S, typename T> | 162 // |
| 85 class CallbackPromiseAdapter final | 163 // Basically CallbackPromiseAdapter<S, T> is a subclass of |
| 86 : public WebCallbacks<typename CallbackPromiseAdapterBase::WebPassType<typen
ame S::WebType>, typename CallbackPromiseAdapterBase::WebPassType<typename T::We
bType>>, public CallbackPromiseAdapterBase { | 164 // WebCallbacks<S::WebType, T::WebType>. There are some exceptions: |
| 87 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | 165 // - If S or T don't have WebType (e.g. S = bool), the trivial WebType holder |
| 88 public: | 166 // is used. For example, CallbackPromiseAdapter<bool, void> is a subclass of |
| 89 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver
> resolver) | 167 // WebCallbacks<bool, void>. |
| 90 : m_resolver(resolver) | 168 // - If a WebType is OwnPtr<T>, its corresponding type parameter on |
| 91 { | 169 // WebCallbacks is WebPassOwnPtr<T>, because WebCallbacks is exposed to |
| 92 ASSERT(m_resolver); | 170 // Chromium. |
| 93 } | 171 // |
| 94 ~CallbackPromiseAdapter() override { } | 172 // When onSuccess is called with a S::WebType value, the value is passed to |
| 95 | 173 // S::take and the resolver is resolved with its return value. Ditto for |
| 96 void onSuccess(WebPassType<typename S::WebType> r) override | 174 // onError. |
| 97 { | 175 // |
| 98 typename S::WebType result(adopt(r)); | 176 // ScriptPromiseResolver::resolve / reject will not be called when the execution |
| 99 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | 177 // context is stopped. |
| 100 return; | 178 template <typename S, typename T> |
| 101 m_resolver->resolve(S::take(m_resolver.get(), pass(result))); | 179 using CallbackPromiseAdapter = CallbackPromiseAdapterInternal::CallbackPromiseAd
apter<S, T>; |
| 102 } | |
| 103 | |
| 104 void onError(WebPassType<typename T::WebType> e) override | |
| 105 { | |
| 106 typename T::WebType error(adopt(e)); | |
| 107 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 108 return; | |
| 109 m_resolver->reject(T::take(m_resolver.get(), pass(error))); | |
| 110 } | |
| 111 | |
| 112 private: | |
| 113 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 114 }; | |
| 115 | |
| 116 template<typename T> | |
| 117 class CallbackPromiseAdapter<void, T> final : public WebCallbacks<void, typename
CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public CallbackP
romiseAdapterBase { | |
| 118 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 119 public: | |
| 120 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver
> resolver) | |
| 121 : m_resolver(resolver) | |
| 122 { | |
| 123 ASSERT(m_resolver); | |
| 124 } | |
| 125 ~CallbackPromiseAdapter() override { } | |
| 126 | |
| 127 void onSuccess() override | |
| 128 { | |
| 129 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 130 return; | |
| 131 m_resolver->resolve(); | |
| 132 } | |
| 133 | |
| 134 void onError(WebPassType<typename T::WebType> e) override | |
| 135 { | |
| 136 typename T::WebType error(adopt(e)); | |
| 137 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 138 return; | |
| 139 m_resolver->reject(T::take(m_resolver.get(), pass(error))); | |
| 140 } | |
| 141 | |
| 142 private: | |
| 143 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 144 }; | |
| 145 | |
| 146 template<typename S> | |
| 147 class CallbackPromiseAdapter<S, void> final : public WebCallbacks<typename Callb
ackPromiseAdapterBase::WebPassType<typename S::WebType>, void>, public CallbackP
romiseAdapterBase { | |
| 148 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 149 public: | |
| 150 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver
> resolver) | |
| 151 : m_resolver(resolver) | |
| 152 { | |
| 153 ASSERT(m_resolver); | |
| 154 } | |
| 155 ~CallbackPromiseAdapter() override { } | |
| 156 | |
| 157 void onSuccess(WebPassType<typename S::WebType> r) override | |
| 158 { | |
| 159 typename S::WebType result(adopt(r)); | |
| 160 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 161 return; | |
| 162 m_resolver->resolve(S::take(m_resolver.get(), pass(result))); | |
| 163 } | |
| 164 | |
| 165 void onError() override | |
| 166 { | |
| 167 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 168 return; | |
| 169 m_resolver->reject(); | |
| 170 } | |
| 171 | |
| 172 private: | |
| 173 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 174 }; | |
| 175 | |
| 176 template<typename T> | |
| 177 class CallbackPromiseAdapter<bool, T> final : public WebCallbacks<bool*, typenam
e CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public Callback
PromiseAdapterBase { | |
| 178 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 179 public: | |
| 180 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver
> resolver) | |
| 181 : m_resolver(resolver) | |
| 182 { | |
| 183 ASSERT(m_resolver); | |
| 184 } | |
| 185 ~CallbackPromiseAdapter() override { } | |
| 186 | |
| 187 // TODO(nhiroki): onSuccess should take ownership of a bool object for | |
| 188 // consistency. (http://crbug.com/493531) | |
| 189 void onSuccess(bool* result) override | |
| 190 { | |
| 191 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 192 return; | |
| 193 m_resolver->resolve(*result); | |
| 194 } | |
| 195 | |
| 196 void onError(WebPassType<typename T::WebType> e) override | |
| 197 { | |
| 198 typename T::WebType error(adopt(e)); | |
| 199 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 200 return; | |
| 201 m_resolver->reject(T::take(m_resolver.get(), pass(error))); | |
| 202 } | |
| 203 | |
| 204 private: | |
| 205 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 206 }; | |
| 207 | |
| 208 template<> | |
| 209 class CallbackPromiseAdapter<void, void> final : public WebCallbacks<void, void>
, public CallbackPromiseAdapterBase { | |
| 210 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 211 public: | |
| 212 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver
> resolver) | |
| 213 : m_resolver(resolver) | |
| 214 { | |
| 215 ASSERT(m_resolver); | |
| 216 } | |
| 217 ~CallbackPromiseAdapter() override { } | |
| 218 | |
| 219 void onSuccess() override | |
| 220 { | |
| 221 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 222 return; | |
| 223 m_resolver->resolve(); | |
| 224 } | |
| 225 | |
| 226 void onError() override | |
| 227 { | |
| 228 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 229 return; | |
| 230 m_resolver->reject(); | |
| 231 } | |
| 232 | |
| 233 private: | |
| 234 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 235 }; | |
| 236 | |
| 237 template<> | |
| 238 class CallbackPromiseAdapter<bool, void> final : public WebCallbacks<bool*, void
>, public CallbackPromiseAdapterBase { | |
| 239 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 240 public: | |
| 241 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver
> resolver) | |
| 242 : m_resolver(resolver) | |
| 243 { | |
| 244 ASSERT(m_resolver); | |
| 245 } | |
| 246 ~CallbackPromiseAdapter() override { } | |
| 247 | |
| 248 // TODO(nhiroki): onSuccess should take ownership of a bool object for | |
| 249 // consistency. (http://crbug.com/493531) | |
| 250 void onSuccess(bool* result) override | |
| 251 { | |
| 252 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 253 return; | |
| 254 m_resolver->resolve(*result); | |
| 255 } | |
| 256 | |
| 257 void onError() override | |
| 258 { | |
| 259 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 260 return; | |
| 261 m_resolver->reject(); | |
| 262 } | |
| 263 | |
| 264 private: | |
| 265 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 266 }; | |
| 267 | 180 |
| 268 } // namespace blink | 181 } // namespace blink |
| 269 | 182 |
| 270 #endif | 183 #endif |
| OLD | NEW |