| 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 // CallbackPromiseAdapter is a WebCallbacks subclass and resolves / rejects the |
| 43 public: | 44 // stored resolver when onSuccess / onError is called, respectively. |
| 44 // The following templates should be gone once the repositories are merged | 45 // |
| 46 // Basically CallbackPromiseAdapter<S, T> is a subclass of |
| 47 // WebCallbacks<S::WebType, T::WebType>. There are some exceptions: |
| 48 // - If S or T don't have WebType (e.g. S = bool), a default WebType holder |
| 49 // called trivial WebType holder is used. For example, |
| 50 // CallbackPromiseAdapter<bool, void> is a subclass of |
| 51 // WebCallbacks<bool, void>. |
| 52 // - If a WebType is OwnPtr<T>, its corresponding type parameter on |
| 53 // WebCallbacks is WebPassOwnPtr<T>, because WebCallbacks must be exposed to |
| 54 // Chromium. |
| 55 // |
| 56 // When onSuccess is called with a S::WebType value, the value is passed to |
| 57 // S::take and the resolver is resolved with its return value. Ditto for |
| 58 // onError. |
| 59 // |
| 60 // ScriptPromiseResolver::resolve / reject will not be called when the execution |
| 61 // context is stopped. |
| 62 // |
| 63 // Example: |
| 64 // class MyClass { |
| 65 // public: |
| 66 // using WebType = OwnPtr<WebMyClass>; |
| 67 // static PassRefPtr<MyClass> take(ScriptPromiseResolver* resolver, |
| 68 // PassOwnPtr<WebMyClass> webInstance) |
| 69 // { |
| 70 // return MyClass::create(webInstance); |
| 71 // } |
| 72 // ... |
| 73 // }; |
| 74 // class MyErrorClass { |
| 75 // public: |
| 76 // using WebType = const WebMyErrorClass&; |
| 77 // static MyErrorClass take(ScriptPromiseResolver* resolver, |
| 78 // const WebErrorClass& webError) |
| 79 // { |
| 80 // return MyErrorClass(webError); |
| 81 // } |
| 82 // ... |
| 83 // }; |
| 84 // OwnPtr<WebCallbacks<WebPassOwnPtr<WebMyClass>, const WebMyErrorClass&>> |
| 85 // callbacks = adoptPtr(new CallbackPromiseAdapter<MyClass, MyErrorClass>( |
| 86 // resolver)); |
| 87 // ... |
| 88 // |
| 89 // OwnPtr<WebCallbacks<bool, const WebMyErrorClass&>> callbacks2 = |
| 90 // adoptPtr(new CallbackPromiseAdapter<bool, MyErrorClass>(resolver)); |
| 91 // ... |
| 92 // |
| 93 // |
| 94 // In order to implement the above exceptions, we have template classes below. |
| 95 // OnSuccess and OnError provide onSuccess and onError implementation, and there |
| 96 // are utility templates that provide |
| 97 // - OwnPtr - WebPassOwnPtr translation ([Web]PassType[Impl], adopt, pass), |
| 98 // - trivial WebType holder (TrivialWebTypeHolder). |
| 99 |
| 100 namespace internal { |
| 101 |
| 102 // This template is placed outside of CallbackPromiseAdapterInternal because |
| 103 // explicit specialization is forbidden in a class scope. |
| 104 template <typename T> |
| 105 struct CallbackPromiseAdapterTrivialWebTypeHolder { |
| 106 using WebType = T; |
| 107 static T take(ScriptPromiseResolver*, const T& x) { return x; } |
| 108 }; |
| 109 template <> |
| 110 struct CallbackPromiseAdapterTrivialWebTypeHolder<void> { |
| 111 using WebType = void; |
| 112 }; |
| 113 |
| 114 class CallbackPromiseAdapterInternal { |
| 115 private: |
| 116 template <typename T> static T webTypeHolderMatcher(typename WTF::RemoveRefe
rence<typename T::WebType>::Type*); |
| 117 template <typename T> static CallbackPromiseAdapterTrivialWebTypeHolder<T> w
ebTypeHolderMatcher(...); |
| 118 template <typename T> using WebTypeHolder = decltype(webTypeHolderMatcher<T>
(nullptr)); |
| 119 |
| 120 // The following templates should be gone when the repositories are merged |
| 45 // and we can use C++11 libraries. | 121 // and we can use C++11 libraries. |
| 46 template <typename T> | 122 template <typename T> |
| 47 struct PassTypeImpl { | 123 struct PassTypeImpl { |
| 48 using Type = T; | 124 using Type = T; |
| 49 }; | 125 }; |
| 50 template <typename T> | 126 template <typename T> |
| 51 struct PassTypeImpl<OwnPtr<T>> { | 127 struct PassTypeImpl<OwnPtr<T>> { |
| 52 using Type = PassOwnPtr<T>; | 128 using Type = PassOwnPtr<T>; |
| 53 }; | 129 }; |
| 54 | |
| 55 template <typename T> | 130 template <typename T> |
| 56 struct WebPassTypeImpl { | 131 struct WebPassTypeImpl { |
| 57 using Type = T; | 132 using Type = T; |
| 58 }; | 133 }; |
| 59 template <typename T> | 134 template <typename T> |
| 60 struct WebPassTypeImpl<OwnPtr<T>> { | 135 struct WebPassTypeImpl<OwnPtr<T>> { |
| 61 using Type = WebPassOwnPtr<T>; | 136 using Type = WebPassOwnPtr<T>; |
| 62 }; | 137 }; |
| 138 template <typename T> using PassType = typename PassTypeImpl<T>::Type; |
| 139 template <typename T> using WebPassType = typename WebPassTypeImpl<T>::Type; |
| 140 template <typename T> static T& adopt(T& x) { return x; } |
| 141 template <typename T> static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { retu
rn x.release(); } |
| 142 template <typename T> static PassType<T> pass(T& x) { return x; } |
| 143 template <typename T> static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.rel
ease(); } |
| 144 |
| 145 template <typename S, typename T> |
| 146 class Base : public WebCallbacks<WebPassType<typename S::WebType>, WebPassTy
pe<typename T::WebType>> { |
| 147 public: |
| 148 explicit Base(ScriptPromiseResolver* resolver) : m_resolver(resolver) {} |
| 149 ScriptPromiseResolver* resolver() { return m_resolver; } |
| 150 |
| 151 private: |
| 152 Persistent<ScriptPromiseResolver> m_resolver; |
| 153 }; |
| 154 |
| 155 template <typename S, typename T> |
| 156 class OnSuccess : public Base<S, T> { |
| 157 public: |
| 158 explicit OnSuccess(ScriptPromiseResolver* resolver) : Base<S, T>(resolve
r) {} |
| 159 void onSuccess(WebPassType<typename S::WebType> r) override |
| 160 { |
| 161 typename S::WebType result(adopt(r)); |
| 162 ScriptPromiseResolver* resolver = this->resolver(); |
| 163 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 164 return; |
| 165 resolver->resolve(S::take(resolver, pass(result))); |
| 166 } |
| 167 }; |
| 63 template <typename T> | 168 template <typename T> |
| 64 using PassType = typename PassTypeImpl<T>::Type; | 169 class OnSuccess<WebTypeHolder<void>, T> : public Base<WebTypeHolder<void>, T
> { |
| 65 template <typename T> | 170 public: |
| 66 using WebPassType = typename WebPassTypeImpl<T>::Type; | 171 explicit OnSuccess(ScriptPromiseResolver* resolver) : Base<WebTypeHolder
<void>, T>(resolver) {} |
| 67 template <typename T> | 172 void onSuccess() override |
| 68 static T& adopt(T& x) { return x; } | 173 { |
| 69 template <typename T> | 174 ScriptPromiseResolver* resolver = this->resolver(); |
| 70 static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { return x.release(); } | 175 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 71 template <typename T> | 176 return; |
| 72 static PassType<T> pass(T& x) { return x; } | 177 resolver->resolve(); |
| 73 template <typename T> | 178 } |
| 74 static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.release(); } | 179 }; |
| 180 template <typename S, typename T> |
| 181 class OnError : public OnSuccess<S, T> { |
| 182 public: |
| 183 explicit OnError(ScriptPromiseResolver* resolver) : OnSuccess<S, T>(reso
lver) {} |
| 184 void onError(WebPassType<typename T::WebType> e) override |
| 185 { |
| 186 typename T::WebType result(adopt(e)); |
| 187 ScriptPromiseResolver* resolver = this->resolver(); |
| 188 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 189 return; |
| 190 resolver->reject(T::take(resolver, pass(result))); |
| 191 } |
| 192 }; |
| 193 template <typename S> |
| 194 class OnError<S, WebTypeHolder<void>> : public OnSuccess<S, WebTypeHolder<vo
id>> { |
| 195 public: |
| 196 explicit OnError(ScriptPromiseResolver* resolver) : OnSuccess<S, WebType
Holder<void>>(resolver) {} |
| 197 void onError() override |
| 198 { |
| 199 ScriptPromiseResolver* resolver = this->resolver(); |
| 200 if (!resolver->executionContext() || resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 201 return; |
| 202 resolver->reject(); |
| 203 } |
| 204 }; |
| 205 |
| 206 public: |
| 207 template <typename S, typename T> |
| 208 class CallbackPromiseAdapter final : public OnError<WebTypeHolder<S>, WebTyp
eHolder<T>> { |
| 209 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); |
| 210 public: |
| 211 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) : OnErr
or<WebTypeHolder<S>, WebTypeHolder<T>>(resolver) {} |
| 212 }; |
| 75 }; | 213 }; |
| 76 | 214 |
| 215 } // namespace internal |
| 77 | 216 |
| 78 // TODO(yhirano): Add comments. | 217 template <typename S, typename T> |
| 79 template<typename S, typename T> | 218 using CallbackPromiseAdapter = internal::CallbackPromiseAdapterInternal::Callbac
kPromiseAdapter<S, T>; |
| 80 class CallbackPromiseAdapter final | |
| 81 : public WebCallbacks<typename CallbackPromiseAdapterBase::WebPassType<typen
ame S::WebType>, typename CallbackPromiseAdapterBase::WebPassType<typename T::We
bType>>, public CallbackPromiseAdapterBase { | |
| 82 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 83 public: | |
| 84 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) | |
| 85 : m_resolver(resolver) | |
| 86 { | |
| 87 ASSERT(m_resolver); | |
| 88 } | |
| 89 ~CallbackPromiseAdapter() override { } | |
| 90 | |
| 91 void onSuccess(WebPassType<typename S::WebType> r) override | |
| 92 { | |
| 93 typename S::WebType result(adopt(r)); | |
| 94 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 95 return; | |
| 96 m_resolver->resolve(S::take(m_resolver.get(), pass(result))); | |
| 97 } | |
| 98 | |
| 99 void onError(WebPassType<typename T::WebType> e) override | |
| 100 { | |
| 101 typename T::WebType error(adopt(e)); | |
| 102 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 103 return; | |
| 104 m_resolver->reject(T::take(m_resolver.get(), pass(error))); | |
| 105 } | |
| 106 | |
| 107 private: | |
| 108 Persistent<ScriptPromiseResolver> m_resolver; | |
| 109 }; | |
| 110 | |
| 111 template<typename T> | |
| 112 class CallbackPromiseAdapter<void, T> final : public WebCallbacks<void, typename
CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public CallbackP
romiseAdapterBase { | |
| 113 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 114 public: | |
| 115 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) | |
| 116 : m_resolver(resolver) | |
| 117 { | |
| 118 ASSERT(m_resolver); | |
| 119 } | |
| 120 ~CallbackPromiseAdapter() override { } | |
| 121 | |
| 122 void onSuccess() override | |
| 123 { | |
| 124 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 125 return; | |
| 126 m_resolver->resolve(); | |
| 127 } | |
| 128 | |
| 129 void onError(WebPassType<typename T::WebType> e) override | |
| 130 { | |
| 131 typename T::WebType error(adopt(e)); | |
| 132 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 133 return; | |
| 134 m_resolver->reject(T::take(m_resolver.get(), pass(error))); | |
| 135 } | |
| 136 | |
| 137 private: | |
| 138 Persistent<ScriptPromiseResolver> m_resolver; | |
| 139 }; | |
| 140 | |
| 141 template<typename S> | |
| 142 class CallbackPromiseAdapter<S, void> final : public WebCallbacks<typename Callb
ackPromiseAdapterBase::WebPassType<typename S::WebType>, void>, public CallbackP
romiseAdapterBase { | |
| 143 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 144 public: | |
| 145 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) | |
| 146 : m_resolver(resolver) | |
| 147 { | |
| 148 ASSERT(m_resolver); | |
| 149 } | |
| 150 ~CallbackPromiseAdapter() override { } | |
| 151 | |
| 152 void onSuccess(WebPassType<typename S::WebType> r) override | |
| 153 { | |
| 154 typename S::WebType result(adopt(r)); | |
| 155 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 156 return; | |
| 157 m_resolver->resolve(S::take(m_resolver.get(), pass(result))); | |
| 158 } | |
| 159 | |
| 160 void onError() override | |
| 161 { | |
| 162 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 163 return; | |
| 164 m_resolver->reject(); | |
| 165 } | |
| 166 | |
| 167 private: | |
| 168 Persistent<ScriptPromiseResolver> m_resolver; | |
| 169 }; | |
| 170 | |
| 171 template<typename T> | |
| 172 class CallbackPromiseAdapter<bool, T> final : public WebCallbacks<bool*, typenam
e CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public Callback
PromiseAdapterBase { | |
| 173 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 174 public: | |
| 175 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) | |
| 176 : m_resolver(resolver) | |
| 177 { | |
| 178 ASSERT(m_resolver); | |
| 179 } | |
| 180 ~CallbackPromiseAdapter() override { } | |
| 181 | |
| 182 // TODO(nhiroki): onSuccess should take ownership of a bool object for | |
| 183 // consistency. (http://crbug.com/493531) | |
| 184 void onSuccess(bool* result) override | |
| 185 { | |
| 186 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 187 return; | |
| 188 m_resolver->resolve(*result); | |
| 189 } | |
| 190 | |
| 191 void onError(WebPassType<typename T::WebType> e) override | |
| 192 { | |
| 193 typename T::WebType error(adopt(e)); | |
| 194 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 195 return; | |
| 196 m_resolver->reject(T::take(m_resolver.get(), pass(error))); | |
| 197 } | |
| 198 | |
| 199 private: | |
| 200 Persistent<ScriptPromiseResolver> m_resolver; | |
| 201 }; | |
| 202 | |
| 203 template<> | |
| 204 class CallbackPromiseAdapter<void, void> final : public WebCallbacks<void, void>
, public CallbackPromiseAdapterBase { | |
| 205 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 206 public: | |
| 207 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) | |
| 208 : m_resolver(resolver) | |
| 209 { | |
| 210 ASSERT(m_resolver); | |
| 211 } | |
| 212 ~CallbackPromiseAdapter() override { } | |
| 213 | |
| 214 void onSuccess() override | |
| 215 { | |
| 216 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 217 return; | |
| 218 m_resolver->resolve(); | |
| 219 } | |
| 220 | |
| 221 void onError() override | |
| 222 { | |
| 223 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 224 return; | |
| 225 m_resolver->reject(); | |
| 226 } | |
| 227 | |
| 228 private: | |
| 229 Persistent<ScriptPromiseResolver> m_resolver; | |
| 230 }; | |
| 231 | |
| 232 template<> | |
| 233 class CallbackPromiseAdapter<bool, void> final : public WebCallbacks<bool*, void
>, public CallbackPromiseAdapterBase { | |
| 234 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
| 235 public: | |
| 236 explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) | |
| 237 : m_resolver(resolver) | |
| 238 { | |
| 239 ASSERT(m_resolver); | |
| 240 } | |
| 241 ~CallbackPromiseAdapter() override { } | |
| 242 | |
| 243 // TODO(nhiroki): onSuccess should take ownership of a bool object for | |
| 244 // consistency. (http://crbug.com/493531) | |
| 245 void onSuccess(bool* result) override | |
| 246 { | |
| 247 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 248 return; | |
| 249 m_resolver->resolve(*result); | |
| 250 } | |
| 251 | |
| 252 void onError() override | |
| 253 { | |
| 254 if (!m_resolver->executionContext() || m_resolver->executionContext()->a
ctiveDOMObjectsAreStopped()) | |
| 255 return; | |
| 256 m_resolver->reject(); | |
| 257 } | |
| 258 | |
| 259 private: | |
| 260 Persistent<ScriptPromiseResolver> m_resolver; | |
| 261 }; | |
| 262 | 219 |
| 263 } // namespace blink | 220 } // namespace blink |
| 264 | 221 |
| 265 #endif | 222 #endif |
| OLD | NEW |