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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/scheduler/BUILD.gn ('k') | components/scheduler/promises/promise.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/scheduler/promises/promise.h
diff --git a/components/scheduler/promises/promise.h b/components/scheduler/promises/promise.h
new file mode 100644
index 0000000000000000000000000000000000000000..1516cff96afafbd0b9be34658f8a63f47f787df8
--- /dev/null
+++ b/components/scheduler/promises/promise.h
@@ -0,0 +1,257 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_PROMISES_PROMISE_H_
+#define COMPONENTS_SCHEDULER_PROMISES_PROMISE_H_
+
+#include "components/scheduler/promises/promise_internal.h"
+
+namespace promise {
+
+template <typename R>
+class SCHEDULER_EXPORT Promise {
+ public:
+ using ReturnType = R;
+ using InternalPromise = internal::Promise<ReturnType>;
+
+ Promise() {}
+
+ explicit Promise(const scoped_refptr<InternalPromise>& promise)
+ : promise_(promise) {}
+
+ // Note this is non-explicit to support implicit conversion to allow
+ // assigning promise::Race(...).Then() to a Promise<R>.
+ Promise(scoped_refptr<InternalPromise>&& promise)
+ : promise_(std::move(promise)) {}
+
+ // A directive that instructs the executor to resolve this promise before
+ // others if possible.
+ void SetEager(bool eager) { promise_->SetThisAndPrerequisitesAsEager(eager); }
+
+ // Cancels execution, can be restarted by PromiseExecutor::StartResolve.
+ void Cancel() { promise_->Cancel(); }
+
+ // This will DCHECK if the promise isn't resolved.
+ template <typename RR = R>
+ internal::enable_if_not_void_t<RR, RR&> GetResolved() {
+ return promise_->GetResolved();
+ }
+
+ // Resolves the promise. May schedule excution of callbacks.
+ template <typename RR = R>
+ internal::enable_if_not_void_t<RR, void> Resolve(const RR& r) {
+ promise_->Resolve(r);
+ }
+
+ // Resolves the promise with a moveable type. May schedule excution of
+ // callbacks.
+ template <typename RR = R>
+ internal::enable_if_not_void_t<RR, void> Resolve(RR&& r) {
+ promise_->Resolve(std::move(r));
+ }
+
+ // Resolves the promise. May schedule excution of callbacks.
+ template <typename RR = R>
+ internal::enable_if_void_t<RR, void> Resolve() {
+ promise_->Resolve();
+ }
+
+ // Rejects the promise. May schedule excution of callbacks.
+ template <typename RR = R, typename T>
+ typename enable_if_rejectable<RR, void>::type Reject(const T& r) {
+ promise_->Reject(r);
+ }
+
+ // Rejects the promise with a moveable type. May schedule excution callbacks.
+ template <typename RR = R, typename T>
+ typename enable_if_rejectable<RR, void>::type Reject(T&& r) {
+ promise_->Reject(std::move(r));
+ }
+
+ // Rejects the promise. May schedule excution of callbacks.
+ template <typename RR = R>
+ typename enable_if_rejectable<RR, void>::type Reject() {
+ promise_->Reject();
+ }
+
+ // Resolves the promise with another promise which is sheduled for execution.
+ // May schedule excution of callbacks.
+ void Resolve(const Promise<R>& promise) {
+ promise_->Resolve(promise->promise_);
+ }
+
+ bool is_resolved() const { return promise_->is_resolved(); }
+
+ bool is_rejected() const { return promise_->is_rejected(); }
+
+ template <typename ThenR, typename... ThenArgs>
+ Promise<ThenR> Then(base::Callback<ThenR(ThenArgs...)>&& cb);
+
+ template <typename ThenR>
+ Promise<ThenR> Then(base::Callback<ThenR()>&& cb);
+
+ template <typename ThenR, typename... ThenArgs>
+ Promise<ThenR> Then(base::Callback<Promise<ThenR>(ThenArgs...)>&& cb);
+
+ template <typename ThenR>
+ Promise<ThenR> Then(base::Callback<Promise<ThenR>()>&& cb);
+
+ private:
+ friend class internal::PromiseExecutor;
+
+ template <typename RR>
+ friend class internal::Promise;
+
+ template <typename RR>
+ friend class internal::RaceSpec;
+
+ template <typename... Promises>
+ friend class internal::AllSpec;
+
+ InternalPromise* promise() const { return promise_.get(); }
+
+ scoped_refptr<InternalPromise> promise_;
+};
+
+// Create promise that will run a callback.
+template <typename R, typename... Args>
+Promise<R> Create(base::Callback<R(Args...)> c) {
+ return Promise<R>(
+ make_scoped_refptr(new internal::FunctionPromise<R, Args...>(c)));
+}
+
+// Create a promise that is already resolved.
+template <typename R>
+Promise<R> Create(const R& r) {
+ scoped_refptr<internal::Promise<R>> promise(new internal::Promise<R>(
+ internal::PromiseBase::PrerequisitePolicy::NEVER));
+ promise->Resolve(r);
+ return Promise<R>(promise);
+}
+
+// Create a promise that is already resolved.
+template <typename R>
+Promise<R> Create(R&& r) {
+ scoped_refptr<internal::Promise<R>> promise(new internal::Promise<R>(
+ internal::PromiseBase::PrerequisitePolicy::NEVER));
+ promise->Resolve(std::move(r));
+ return Promise<R>(promise);
+}
+
+// Create a promise that is manually resolved.
+template <typename R>
+Promise<R> Create() {
+ return Promise<R>(make_scoped_refptr(new internal::Promise<R>(
+ internal::PromiseBase::PrerequisitePolicy::NEVER)));
+}
+
+// ===
+
+template <typename R>
+template <typename ThenR, typename... ThenArgs>
+Promise<ThenR> Promise<R>::Then(base::Callback<ThenR(ThenArgs...)>&& cb) {
+ using PromiseType = internal::Promise<R>;
+ return Promise<ThenR>(
+ make_scoped_refptr(new internal::RacePromises<ThenR, ThenR, PromiseType>(
+ std::move(cb), {promise_})));
+}
+
+template <>
+template <typename ThenR>
+Promise<ThenR> Promise<void>::Then(base::Callback<ThenR()>&& cb) {
+ return Promise<ThenR>(make_scoped_refptr(
+ new internal::RaceVoidPromises<ThenR, ThenR>(std::move(cb), {promise_})));
+}
+
+template <typename R>
+template <typename ThenR, typename... ThenArgs>
+Promise<ThenR> Promise<R>::Then(
+ base::Callback<Promise<ThenR>(ThenArgs...)>&& cb) {
+ using PromiseType = internal::Promise<R>;
+ return Promise<ThenR>(make_scoped_refptr(
+ new internal::RacePromises<ThenR, Promise<ThenR>, PromiseType>(
+ std::move(cb), {promise_})));
+}
+
+template <>
+template <typename ThenR>
+Promise<ThenR> Promise<void>::Then(base::Callback<Promise<ThenR>()>&& cb) {
+ return Promise<ThenR>(make_scoped_refptr<internal::Promise<ThenR>>(
+ new internal::RaceVoidPromises<ThenR, Promise<ThenR>>(std::move(cb),
+ {promise_})));
+}
+
+// ===
+
+/*
+Promises::All(promises...).Then(callback) allows you to schedule a callback to
+run once all of the specified promises have been resolved.
+
+The promises specified must either be all void or all non-void. In the case of
+non-void promises, the callback specified by Then() is called with results of
+the promises.
+
+Race(...).Then() returns a promise which you need to schedule for execution.
+E.g.
+
+Promise<int> p1;
+Promise<bool> p2;
+Promise<float> p3;
+
+void MyFunc(int, bool, float);
+
+...
+Promise<void> p(
+ promise::All(p1, p2, p3).Then(base::Bind(&MyFunc));
+
+// Schedule p1, p2 & p3 for execution and once they're run call MyFunc with
+// their return values.
+my_executor_->StartResolve(p);
+*/
+template <typename... Promises>
+internal::AllSpec<Promises...> All(Promises... promises) {
+ static_assert(
+ internal::check_all_same_type<Promise<void>, Promises...>::value ||
+ !internal::check_any_have_type<Promise<void>, Promises...>::value,
+ "All(...) requires the promises to either be all void or all non-void.");
+ return internal::AllSpec<Promises...>(promises...);
+}
+
+/*
+Promises::Race(promises...).Then(callback) allows you to schedule a callback to
+run once any of the specified promises have been resolved.
+
+The promises must all have the same type. If the promises are non-void, then
+the callback specified by Then() is called with results of the sellected
+resolved promise. The selection algorithm works as follows, when attempting to
+run the callback, the promises specifed in the Race(...) clause are examined in
+order and the first resolved one is selected.
+
+All(...).Then() returns a promise which you need to schedule for execution. E.g.
+
+ Promise<int> p1;
+ Promise<int> p2;
+ Promise<int> p3;
+
+ void MyFunc(int);
+
+ ...
+ Promise<void> p(
+ promise::Race(p1, p2, p3).Then(base::Bind(&MyFunc));
+
+ // Schedule p1, p2 & p3 for execution and once any of them have been run. When
+ // deciding which promise to call MyFunc the promises from the Race() clause
+ // scanned in order and the the first resolved one is used.
+ my_executor_->StartResolve(p);
+*/
+template <typename R, typename... Promises>
+internal::RaceSpec<R> Race(Promise<R> r1, Promises... promises) {
+ static_assert(internal::check_all_same_type<Promise<R>, Promises...>::value,
+ "Race(...) requires all the promises to have the same type.");
+ return internal::RaceSpec<R>(r1, promises...);
+}
+
+} // namespace promise
+
+#endif // COMPONENTS_SCHEDULER_PROMISES_PROMISE_H_
« 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