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 // In order to implement the above exceptions, we have template classes below. | |
64 // OnSuccess and OnError provide onSuccess and onError implementation, and there | |
65 // are utility templates that provide | |
66 // - OwnPtr - WebPassOwnPtr translation ([Web]PassType[Impl], adopt, pass), | |
67 // - trivial WebType holder (TrivialWebTypeHolder). | |
scheib
2015/07/27 17:39:18
Please include sample best-practice use code snipp
yhirano
2015/07/29 04:22:35
Done.
| |
68 | |
69 namespace internal { | |
70 | |
71 // This template is placed outside of CallbackPromiseAdapterInternal because | |
72 // explicit specialization is forbidden in a class scope. | |
73 template <typename T> | |
74 struct CallbackPromiseAdapterTrivialWebTypeHolder { | |
75 using WebType = T; | |
76 static T take(ScriptPromiseResolver*, const T& x) { return x; } | |
77 }; | |
78 template <> | |
79 struct CallbackPromiseAdapterTrivialWebTypeHolder<void> { | |
80 using WebType = void; | |
81 }; | |
82 | |
83 class CallbackPromiseAdapterInternal { | |
84 private: | |
85 template <typename T> static T webTypeHolderMatcher(typename WTF::RemoveRefe rence<typename T::WebType>::Type*); | |
86 template <typename T> static CallbackPromiseAdapterTrivialWebTypeHolder<T> w ebTypeHolderMatcher(...); | |
87 template <typename T> using WebTypeHolder = decltype(webTypeHolderMatcher<T> (nullptr)); | |
88 | |
89 // The following templates should be gone when the repositories are merged | |
45 // and we can use C++11 libraries. | 90 // and we can use C++11 libraries. |
46 template <typename T> | 91 template <typename T> |
47 struct PassTypeImpl { | 92 struct PassTypeImpl { |
48 using Type = T; | 93 using Type = T; |
49 }; | 94 }; |
50 template <typename T> | 95 template <typename T> |
51 struct PassTypeImpl<OwnPtr<T>> { | 96 struct PassTypeImpl<OwnPtr<T>> { |
52 using Type = PassOwnPtr<T>; | 97 using Type = PassOwnPtr<T>; |
53 }; | 98 }; |
54 | |
55 template <typename T> | 99 template <typename T> |
56 struct WebPassTypeImpl { | 100 struct WebPassTypeImpl { |
57 using Type = T; | 101 using Type = T; |
58 }; | 102 }; |
59 template <typename T> | 103 template <typename T> |
60 struct WebPassTypeImpl<OwnPtr<T>> { | 104 struct WebPassTypeImpl<OwnPtr<T>> { |
61 using Type = WebPassOwnPtr<T>; | 105 using Type = WebPassOwnPtr<T>; |
62 }; | 106 }; |
107 template <typename T> using PassType = typename PassTypeImpl<T>::Type; | |
108 template <typename T> using WebPassType = typename WebPassTypeImpl<T>::Type; | |
109 template <typename T> static T& adopt(T& x) { return x; } | |
110 template <typename T> static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { retu rn x.release(); } | |
111 template <typename T> static PassType<T> pass(T& x) { return x; } | |
112 template <typename T> static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.rel ease(); } | |
113 | |
114 template <typename S, typename T> | |
115 class Base : public WebCallbacks<WebPassType<typename S::WebType>, WebPassTy pe<typename T::WebType>> { | |
116 public: | |
117 explicit Base(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : m_resolver(resolver) {} | |
118 ScriptPromiseResolver* resolver() { return m_resolver.get(); } | |
119 | |
120 private: | |
121 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
122 }; | |
123 | |
124 template <typename S, typename T> | |
125 class OnSuccess : public Base<S, T> { | |
126 public: | |
127 explicit OnSuccess(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve r) : Base<S, T>(resolver) {} | |
128 void onSuccess(WebPassType<typename S::WebType> r) override | |
129 { | |
130 typename S::WebType result(adopt(r)); | |
131 ScriptPromiseResolver* resolver = this->resolver(); | |
132 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
133 return; | |
134 resolver->resolve(S::take(resolver, pass(result))); | |
135 } | |
136 }; | |
63 template <typename T> | 137 template <typename T> |
64 using PassType = typename PassTypeImpl<T>::Type; | 138 class OnSuccess<WebTypeHolder<void>, T> : public Base<WebTypeHolder<void>, T > { |
65 template <typename T> | 139 public: |
66 using WebPassType = typename WebPassTypeImpl<T>::Type; | 140 explicit OnSuccess(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve r) : Base<WebTypeHolder<void>, T>(resolver) {} |
67 template <typename T> | 141 void onSuccess() override |
68 static T& adopt(T& x) { return x; } | 142 { |
69 template <typename T> | 143 ScriptPromiseResolver* resolver = this->resolver(); |
70 static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { return x.release(); } | 144 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) |
71 template <typename T> | 145 return; |
72 static PassType<T> pass(T& x) { return x; } | 146 resolver->resolve(); |
73 template <typename T> | 147 } |
74 static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.release(); } | 148 }; |
149 template <typename S, typename T> | |
150 class OnError : public OnSuccess<S, T> { | |
151 public: | |
152 explicit OnError(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : OnSuccess<S, T>(resolver) {} | |
153 void onError(WebPassType<typename T::WebType> e) override | |
154 { | |
155 typename T::WebType result(adopt(e)); | |
156 ScriptPromiseResolver* resolver = this->resolver(); | |
157 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
158 return; | |
159 resolver->reject(T::take(resolver, pass(result))); | |
160 } | |
161 }; | |
162 template <typename S> | |
163 class OnError<S, WebTypeHolder<void>> : public OnSuccess<S, WebTypeHolder<vo id>> { | |
164 public: | |
165 explicit OnError(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : OnSuccess<S, WebTypeHolder<void>>(resolver) {} | |
166 void onError() override | |
167 { | |
168 ScriptPromiseResolver* resolver = this->resolver(); | |
169 if (!resolver->executionContext() || resolver->executionContext()->a ctiveDOMObjectsAreStopped()) | |
170 return; | |
171 resolver->reject(); | |
172 } | |
173 }; | |
174 | |
175 public: | |
176 template <typename S, typename T> | |
177 class CallbackPromiseAdapter final : public OnError<WebTypeHolder<S>, WebTyp eHolder<T>> { | |
178 WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter); | |
179 public: | |
180 explicit CallbackPromiseAdapter(PassRefPtrWillBeRawPtr<ScriptPromiseReso lver> resolver) : OnError<WebTypeHolder<S>, WebTypeHolder<T>>(resolver) {} | |
181 }; | |
75 }; | 182 }; |
76 | 183 |
184 } // namespace internal | |
77 | 185 |
78 // TODO(yhirano): Add comments. | 186 template <typename S, typename T> |
79 template<typename S, typename T> | 187 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(PassRefPtrWillBeRawPtr<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 RefPtrWillBePersistent<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(PassRefPtrWillBeRawPtr<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 RefPtrWillBePersistent<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(PassRefPtrWillBeRawPtr<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 RefPtrWillBePersistent<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(PassRefPtrWillBeRawPtr<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 RefPtrWillBePersistent<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(PassRefPtrWillBeRawPtr<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 RefPtrWillBePersistent<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(PassRefPtrWillBeRawPtr<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 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
261 }; | |
262 | 188 |
263 } // namespace blink | 189 } // namespace blink |
264 | 190 |
265 #endif | 191 #endif |
OLD | NEW |