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 |
kinuko
2015/07/26 15:15:08
nit: for files that heavily use templates I prefer
yhirano
2015/07/27 05:30:02
Done.
CallbackPromiseAdapterInternal in internal
kinuko
2015/07/27 05:59:00
Thanks, I still prefer having them in internal (bu
| |
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 once allowed. | |
49 // https://chromium-cpp.appspot.com/ | |
50 static T take(ScriptPromiseResolver*, const T& x) { return x; } | |
51 }; | |
52 template <> | |
53 struct CallbackPromiseAdapterTrivialWebTypeHolder<void> { | |
54 using WebType = void; | |
55 }; | |
56 | |
57 class CallbackPromiseAdapterInternal { | |
58 private: | |
59 template <typename T> static T webTypeHolderMatcher(typename WTF::RemoveRefe rence<typename T::WebType>::Type*); | |
60 template <typename T> static CallbackPromiseAdapterTrivialWebTypeHolder<T> w ebTypeHolderMatcher(...); | |
61 template <typename T> using WebTypeHolder = decltype(webTypeHolderMatcher<T> (nullptr)); | |
62 | |
63 // TODO(yhirano): Use scoped_ptr. | |
44 template <typename T> | 64 template <typename T> |
45 struct PassTypeImpl { | 65 struct PassTypeImpl { |
46 using Type = T; | 66 using Type = T; |
47 }; | 67 }; |
48 template <typename T> | 68 template <typename T> |
49 struct PassTypeImpl<OwnPtr<T>> { | 69 struct PassTypeImpl<OwnPtr<T>> { |
50 using Type = PassOwnPtr<T>; | 70 using Type = PassOwnPtr<T>; |
51 }; | 71 }; |
52 | |
53 template <typename T> | 72 template <typename T> |
54 struct WebPassTypeImpl { | 73 struct WebPassTypeImpl { |
55 using Type = T; | 74 using Type = T; |
56 }; | 75 }; |
57 template <typename T> | 76 template <typename T> |
58 struct WebPassTypeImpl<OwnPtr<T>> { | 77 struct WebPassTypeImpl<OwnPtr<T>> { |
59 using Type = WebPassOwnPtr<T>; | 78 using Type = WebPassOwnPtr<T>; |
60 }; | 79 }; |
61 | 80 template <typename T> using PassType = typename PassTypeImpl<T>::Type; |
62 template <typename T> | 81 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 | 82 |
67 // TODO(yhirano): Use universal reference and std::forward once they are | 83 // TODO(yhirano): Use universal reference and std::forward once they are |
68 // allowed. https://chromium-cpp.appspot.com/ | 84 // allowed. https://chromium-cpp.appspot.com/ |
69 template <typename T> | 85 template <typename T> static T& adopt(T& x) { return x; } |
70 static T& adopt(T& x) { return x; } | 86 template <typename T> static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { retu rn x.release(); } |
71 template <typename T> | |
72 static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { return x.release(); } | |
73 | 87 |
74 // TODO(yhirano): Use rvalue reference and std::move once they are allowed. | 88 // TODO(yhirano): Use rvalue reference and std::move once they are allowed. |
75 // https://chromium-cpp.appspot.com/ | 89 // https://chromium-cpp.appspot.com/ |
90 template <typename T> static PassType<T> pass(T& x) { return x; } | |
91 template <typename T> static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.rel ease(); } | |
92 | |
93 template <typename S, typename T> | |
94 class Base : public WebCallbacks<WebPassType<typename S::WebType>, WebPassTy pe<typename T::WebType>> { | |
95 public: | |
96 explicit Base(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : m_resolver(resolver) {} | |
97 ScriptPromiseResolver* resolver() { return m_resolver.get(); } | |
98 | |
99 private: | |
100 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
101 }; | |
102 | |
103 template <typename S, typename T> | |
104 class OnSuccess : public Base<S, T> { | |
kinuko
2015/07/26 15:15:08
Um... would it be possible / make sense to define
yhirano
2015/07/27 05:30:01
I wanted to do so but I couldn't. I think the prop
kinuko
2015/07/27 05:59:00
Hm, ok...
| |
105 public: | |
106 explicit OnSuccess(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve r) : Base<S, T>(resolver) {} | |
107 void onSuccess(WebPassType<typename S::WebType> r) override | |
108 { | |
109 typename S::WebType result(adopt(r)); | |
110 ScriptPromiseResolver* resolver = this->resolver(); | |
111 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
112 return; | |
113 resolver->resolve(S::take(resolver, pass(result))); | |
114 } | |
115 }; | |
76 template <typename T> | 116 template <typename T> |
77 static PassType<T> pass(T& x) { return x; } | 117 class OnSuccess<WebTypeHolder<void>, T> : public Base<WebTypeHolder<void>, T > { |
78 template <typename T> | 118 public: |
79 static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.release(); } | 119 explicit OnSuccess(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve r) : Base<WebTypeHolder<void>, T>(resolver) {} |
120 void onSuccess() override | |
121 { | |
122 ScriptPromiseResolver* resolver = this->resolver(); | |
123 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
124 return; | |
125 resolver->resolve(); | |
126 } | |
127 }; | |
128 template <typename S, typename T> | |
129 class OnError : public OnSuccess<S, T> { | |
130 public: | |
131 explicit OnError(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : OnSuccess<S, T>(resolver) {} | |
132 void onError(WebPassType<typename T::WebType> e) override | |
133 { | |
134 typename T::WebType result(adopt(e)); | |
135 ScriptPromiseResolver* resolver = this->resolver(); | |
136 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
137 return; | |
138 resolver->reject(T::take(resolver, pass(result))); | |
139 } | |
140 }; | |
141 template <typename S> | |
142 class OnError<S, WebTypeHolder<void>> : public OnSuccess<S, WebTypeHolder<vo id>> { | |
143 public: | |
144 explicit OnError(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : OnSuccess<S, WebTypeHolder<void>>(resolver) {} | |
145 void onError() override | |
146 { | |
147 ScriptPromiseResolver* resolver = this->resolver(); | |
148 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
149 return; | |
150 resolver->reject(); | |
151 } | |
152 }; | |
153 | |
154 public: | |
155 template <typename S, typename T> | |
156 class CallbackPromiseAdapter final : public OnError<WebTypeHolder<S>, WebTyp eHolder<T>> { | |
157 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
158 public: | |
159 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseReso lver> resolver) : OnError<WebTypeHolder<S>, WebTypeHolder<T>>(resolver) {} | |
160 }; | |
80 }; | 161 }; |
81 | 162 |
82 | 163 // CallbackPromiseAdapter is a WebCallbacks subclass and resolves / rejects the |
83 // TODO(yhirano): Add comments. | 164 // stored resolver when onSuccess / onError is called, respectively. |
84 template<typename S, typename T> | 165 // |
85 class CallbackPromiseAdapter final | 166 // 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 { | 167 // WebCallbacks<S::WebType, T::WebType>. There are some exceptions: |
87 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | 168 // - If S or T don't have WebType (e.g. S = bool), the trivial WebType holder |
88 public: | 169 // is used. For example, CallbackPromiseAdapter<bool, void> is a subclass of |
89 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseResolver > resolver) | 170 // WebCallbacks<bool, void>. |
90 : m_resolver(resolver) | 171 // - If a WebType is OwnPtr<T>, its corresponding type parameter on |
91 { | 172 // WebCallbacks is WebPassOwnPtr<T>, because WebCallbacks is exposed to |
92 ASSERT(m_resolver); | 173 // Chromium. |
93 } | 174 // |
94 ~CallbackPromiseAdapter() override { } | 175 // When onSuccess is called with a S::WebType value, the value is passed to |
95 | 176 // S::take and the resolver is resolved with its return value. Ditto for |
96 void onSuccess(WebPassType<typename S::WebType> r) override | 177 // onError. |
97 { | 178 // |
98 typename S::WebType result(adopt(r)); | 179 // ScriptPromiseResolver::resolve / reject will not be called when the execution |
99 if (!m_resolver->executionContext() || m_resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | 180 // context is stopped. |
100 return; | 181 template <typename S, typename T> |
101 m_resolver->resolve(S::take(m_resolver.get(), pass(result))); | 182 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 | 183 |
268 } // namespace blink | 184 } // namespace blink |
269 | 185 |
270 #endif | 186 #endif |
OLD | NEW |