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