Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: components/scheduler/promises/promise.h

Issue 1401553002: NOT INTENDED FOR LANDING: A promises demo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Support for rejectatble promises! Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/scheduler/BUILD.gn ('k') | components/scheduler/promises/promise.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_SCHEDULER_PROMISES_PROMISE_H_
6 #define COMPONENTS_SCHEDULER_PROMISES_PROMISE_H_
7
8 #include "components/scheduler/promises/promise_internal.h"
9
10 namespace promise {
11
12 template <typename R>
13 class SCHEDULER_EXPORT Promise {
14 public:
15 using ReturnType = R;
16 using InternalPromise = internal::Promise<ReturnType>;
17
18 Promise() {}
19
20 explicit Promise(const scoped_refptr<InternalPromise>& promise)
21 : promise_(promise) {}
22
23 // Note this is non-explicit to support implicit conversion to allow
24 // assigning promise::Race(...).Then() to a Promise<R>.
25 Promise(scoped_refptr<InternalPromise>&& promise)
26 : promise_(std::move(promise)) {}
27
28 // A directive that instructs the executor to resolve this promise before
29 // others if possible.
30 void SetEager(bool eager) { promise_->SetThisAndPrerequisitesAsEager(eager); }
31
32 // Cancels execution, can be restarted by PromiseExecutor::StartResolve.
33 void Cancel() { promise_->Cancel(); }
34
35 // This will DCHECK if the promise isn't resolved.
36 template <typename RR = R>
37 internal::enable_if_not_void_t<RR, RR&> GetResolved() {
38 return promise_->GetResolved();
39 }
40
41 // Resolves the promise. May schedule excution of callbacks.
42 template <typename RR = R>
43 internal::enable_if_not_void_t<RR, void> Resolve(const RR& r) {
44 promise_->Resolve(r);
45 }
46
47 // Resolves the promise with a moveable type. May schedule excution of
48 // callbacks.
49 template <typename RR = R>
50 internal::enable_if_not_void_t<RR, void> Resolve(RR&& r) {
51 promise_->Resolve(std::move(r));
52 }
53
54 // Resolves the promise. May schedule excution of callbacks.
55 template <typename RR = R>
56 internal::enable_if_void_t<RR, void> Resolve() {
57 promise_->Resolve();
58 }
59
60 // Rejects the promise. May schedule excution of callbacks.
61 template <typename RR = R, typename T>
62 typename enable_if_rejectable<RR, void>::type Reject(const T& r) {
63 promise_->Reject(r);
64 }
65
66 // Rejects the promise with a moveable type. May schedule excution callbacks.
67 template <typename RR = R, typename T>
68 typename enable_if_rejectable<RR, void>::type Reject(T&& r) {
69 promise_->Reject(std::move(r));
70 }
71
72 // Rejects the promise. May schedule excution of callbacks.
73 template <typename RR = R>
74 typename enable_if_rejectable<RR, void>::type Reject() {
75 promise_->Reject();
76 }
77
78 // Resolves the promise with another promise which is sheduled for execution.
79 // May schedule excution of callbacks.
80 void Resolve(const Promise<R>& promise) {
81 promise_->Resolve(promise->promise_);
82 }
83
84 bool is_resolved() const { return promise_->is_resolved(); }
85
86 bool is_rejected() const { return promise_->is_rejected(); }
87
88 template <typename ThenR, typename... ThenArgs>
89 Promise<ThenR> Then(base::Callback<ThenR(ThenArgs...)>&& cb);
90
91 template <typename ThenR>
92 Promise<ThenR> Then(base::Callback<ThenR()>&& cb);
93
94 template <typename ThenR, typename... ThenArgs>
95 Promise<ThenR> Then(base::Callback<Promise<ThenR>(ThenArgs...)>&& cb);
96
97 template <typename ThenR>
98 Promise<ThenR> Then(base::Callback<Promise<ThenR>()>&& cb);
99
100 private:
101 friend class internal::PromiseExecutor;
102
103 template <typename RR>
104 friend class internal::Promise;
105
106 template <typename RR>
107 friend class internal::RaceSpec;
108
109 template <typename... Promises>
110 friend class internal::AllSpec;
111
112 InternalPromise* promise() const { return promise_.get(); }
113
114 scoped_refptr<InternalPromise> promise_;
115 };
116
117 // Create promise that will run a callback.
118 template <typename R, typename... Args>
119 Promise<R> Create(base::Callback<R(Args...)> c) {
120 return Promise<R>(
121 make_scoped_refptr(new internal::FunctionPromise<R, Args...>(c)));
122 }
123
124 // Create a promise that is already resolved.
125 template <typename R>
126 Promise<R> Create(const R& r) {
127 scoped_refptr<internal::Promise<R>> promise(new internal::Promise<R>(
128 internal::PromiseBase::PrerequisitePolicy::NEVER));
129 promise->Resolve(r);
130 return Promise<R>(promise);
131 }
132
133 // Create a promise that is already resolved.
134 template <typename R>
135 Promise<R> Create(R&& r) {
136 scoped_refptr<internal::Promise<R>> promise(new internal::Promise<R>(
137 internal::PromiseBase::PrerequisitePolicy::NEVER));
138 promise->Resolve(std::move(r));
139 return Promise<R>(promise);
140 }
141
142 // Create a promise that is manually resolved.
143 template <typename R>
144 Promise<R> Create() {
145 return Promise<R>(make_scoped_refptr(new internal::Promise<R>(
146 internal::PromiseBase::PrerequisitePolicy::NEVER)));
147 }
148
149 // ===
150
151 template <typename R>
152 template <typename ThenR, typename... ThenArgs>
153 Promise<ThenR> Promise<R>::Then(base::Callback<ThenR(ThenArgs...)>&& cb) {
154 using PromiseType = internal::Promise<R>;
155 return Promise<ThenR>(
156 make_scoped_refptr(new internal::RacePromises<ThenR, ThenR, PromiseType>(
157 std::move(cb), {promise_})));
158 }
159
160 template <>
161 template <typename ThenR>
162 Promise<ThenR> Promise<void>::Then(base::Callback<ThenR()>&& cb) {
163 return Promise<ThenR>(make_scoped_refptr(
164 new internal::RaceVoidPromises<ThenR, ThenR>(std::move(cb), {promise_})));
165 }
166
167 template <typename R>
168 template <typename ThenR, typename... ThenArgs>
169 Promise<ThenR> Promise<R>::Then(
170 base::Callback<Promise<ThenR>(ThenArgs...)>&& cb) {
171 using PromiseType = internal::Promise<R>;
172 return Promise<ThenR>(make_scoped_refptr(
173 new internal::RacePromises<ThenR, Promise<ThenR>, PromiseType>(
174 std::move(cb), {promise_})));
175 }
176
177 template <>
178 template <typename ThenR>
179 Promise<ThenR> Promise<void>::Then(base::Callback<Promise<ThenR>()>&& cb) {
180 return Promise<ThenR>(make_scoped_refptr<internal::Promise<ThenR>>(
181 new internal::RaceVoidPromises<ThenR, Promise<ThenR>>(std::move(cb),
182 {promise_})));
183 }
184
185 // ===
186
187 /*
188 Promises::All(promises...).Then(callback) allows you to schedule a callback to
189 run once all of the specified promises have been resolved.
190
191 The promises specified must either be all void or all non-void. In the case of
192 non-void promises, the callback specified by Then() is called with results of
193 the promises.
194
195 Race(...).Then() returns a promise which you need to schedule for execution.
196 E.g.
197
198 Promise<int> p1;
199 Promise<bool> p2;
200 Promise<float> p3;
201
202 void MyFunc(int, bool, float);
203
204 ...
205 Promise<void> p(
206 promise::All(p1, p2, p3).Then(base::Bind(&MyFunc));
207
208 // Schedule p1, p2 & p3 for execution and once they're run call MyFunc with
209 // their return values.
210 my_executor_->StartResolve(p);
211 */
212 template <typename... Promises>
213 internal::AllSpec<Promises...> All(Promises... promises) {
214 static_assert(
215 internal::check_all_same_type<Promise<void>, Promises...>::value ||
216 !internal::check_any_have_type<Promise<void>, Promises...>::value,
217 "All(...) requires the promises to either be all void or all non-void.");
218 return internal::AllSpec<Promises...>(promises...);
219 }
220
221 /*
222 Promises::Race(promises...).Then(callback) allows you to schedule a callback to
223 run once any of the specified promises have been resolved.
224
225 The promises must all have the same type. If the promises are non-void, then
226 the callback specified by Then() is called with results of the sellected
227 resolved promise. The selection algorithm works as follows, when attempting to
228 run the callback, the promises specifed in the Race(...) clause are examined in
229 order and the first resolved one is selected.
230
231 All(...).Then() returns a promise which you need to schedule for execution. E.g.
232
233 Promise<int> p1;
234 Promise<int> p2;
235 Promise<int> p3;
236
237 void MyFunc(int);
238
239 ...
240 Promise<void> p(
241 promise::Race(p1, p2, p3).Then(base::Bind(&MyFunc));
242
243 // Schedule p1, p2 & p3 for execution and once any of them have been run. When
244 // deciding which promise to call MyFunc the promises from the Race() clause
245 // scanned in order and the the first resolved one is used.
246 my_executor_->StartResolve(p);
247 */
248 template <typename R, typename... Promises>
249 internal::RaceSpec<R> Race(Promise<R> r1, Promises... promises) {
250 static_assert(internal::check_all_same_type<Promise<R>, Promises...>::value,
251 "Race(...) requires all the promises to have the same type.");
252 return internal::RaceSpec<R>(r1, promises...);
253 }
254
255 } // namespace promise
256
257 #endif // COMPONENTS_SCHEDULER_PROMISES_PROMISE_H_
OLDNEW
« no previous file with comments | « components/scheduler/BUILD.gn ('k') | components/scheduler/promises/promise.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698