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

Unified Diff: Source/core/dom/Future.cpp

Issue 15786003: WIP don't review: Implement Future (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 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
Index: Source/core/dom/Future.cpp
diff --git a/Source/core/dom/Future.cpp b/Source/core/dom/Future.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..109e84ed48b7cfccea95ea8d0e42beee58d6f442
--- /dev/null
+++ b/Source/core/dom/Future.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/dom/Future.h"
+
+#include "bindings/v8/V8Utilities.h"
+#include "core/dom/AnyCallback.h"
+#include "core/platform/Logging.h"
+
+namespace WebCore {
+
+namespace {
+
+class ProcessAcceptCallbacksTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<ProcessAcceptCallbacksTask> create(PassRefPtr<Future> future, const ScriptValue& value)
+ {
+ return adoptPtr(new ProcessAcceptCallbacksTask(future, value));
+ }
+
+ virtual void performTask(ScriptExecutionContext*) OVERRIDE
+ {
+ LOG(Network, "ProcessAcceptCallbacksTask::performTask %d", m_future.get()->refCount());
+ m_future->processAcceptCallbacks(m_value);
+ }
+
+private:
+ ProcessAcceptCallbacksTask(PassRefPtr<Future> future, const ScriptValue& value)
+ : m_future(future)
+ , m_value(value)
+ {
+ }
+
+ RefPtr<Future> m_future;
+ ScriptValue m_value;
+};
+
+class ProcessRejectCallbacksTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<ProcessRejectCallbacksTask> create(PassRefPtr<Future> future, const ScriptValue& value)
+ {
+ return adoptPtr(new ProcessRejectCallbacksTask(future, value));
+ }
+
+ virtual void performTask(ScriptExecutionContext*) OVERRIDE
+ {
+ LOG(Network, "ProcessRejectCallbacksTask::performTask %d", m_future.get()->refCount());
+
+ m_future->processRejectCallbacks(m_value);
+ }
+
+private:
+ ProcessRejectCallbacksTask(PassRefPtr<Future> future, const ScriptValue& value)
+ : m_future(future)
+ , m_value(value)
+ {
+ }
+
+ RefPtr<Future> m_future;
+ ScriptValue m_value;
+};
+
+} // namespace
+
+PassRefPtr<Future> Future::create()
+{
+ LOG(Network, "Future::create start");
+
+ ScriptExecutionContext* context = getScriptExecutionContext();
+
+ RefPtr<Future> future = adoptRef(new Future(context));
+
+ RefPtr<FutureResolver> resolver = FutureResolver::create(future);
+ future->setResolver(resolver);
+
+ return future;
+}
+
+PassRefPtr<Future> Future::createAndRunInit(PassRefPtr<FutureInit> init)
+{
+ RefPtr<Future> future = Future::create();
+
+ LOG(Network, "Future::create call init start %d", future->refCount());
+
+ RefPtr<FutureResolver> resolver = future->getResolver();
+
+ ScriptExecutionContext* context = getScriptExecutionContext();
+
+ // Pass future as this as specified in the spec.
+ ScriptValue result = init->call(resolver, future, context);
+ if (!result.hasNoValue())
+ resolver->rejectInternal(result, false);
+
+ LOG(Network, "Future::create call init done");
+
+ return future;
+}
+
+Future::Future(ScriptExecutionContext* context)
+ : ActiveDOMObject(context)
+ , m_state(Pending)
+{
+ LOG(Network, "Future::Future start %d", refCount());
+
+ suspendIfNeeded();
+}
+
+Future::~Future()
+{
+ LOG(Network, "Future dtor");
+}
+
+PassRefPtr<Future> Future::accept(const ScriptValue& value)
+{
+ RefPtr<Future> future = Future::create();
+ future->getResolver()->accept(value);
+
+ LOG(Network, "Future::accept end %d", future->refCount());
+
+ return future;
+}
+
+PassRefPtr<Future> Future::resolve(const ScriptValue& value)
+{
+ return 0;
+}
+
+PassRefPtr<Future> Future::reject(const ScriptValue& value)
+{
+ RefPtr<Future> future = Future::create();
+ future->getResolver()->reject(value);
+
+ return future;
+}
+
+PassRefPtr<Future> Future::anyof(Vector<ScriptValue>& values)
+{
+ return 0;
+}
+
+PassRefPtr<Future> Future::every(Vector<ScriptValue>& values)
+{
+ return 0;
+}
+
+PassRefPtr<Future> Future::some(Vector<ScriptValue>& values)
+{
+ return 0;
+}
+
+void Future::FutureCallback::invoke(const ScriptValue& value)
+{
+ LOG(Network, "invoke %d", m_algorithm);
+
+ bool exceptionThrown = false;
+ switch (m_algorithm) {
+ case NoAlgorithm:
+ m_callback->call(value, 0, &exceptionThrown);
+ break;
+ case WrapperAlgorithm:
+ ASSERT(m_callback);
+ {
+ ScriptValue result = m_callback->call(value, m_resolver->getFuture(), &exceptionThrown);
+ if (exceptionThrown)
+ m_resolver->rejectInternal(result, true);
+ // FIXME
+ // else
+ // m_resolver->resolveInternal(result, true);
+ else
+ m_resolver->acceptInternal(result, true);
+ }
+ break;
+ case AcceptAlgorithm:
+ m_resolver->acceptInternal(value, true);
+ break;
+ case ResolveAlgorithm:
+ // FIXME
+ // m_resolver->resolveInternal(value, true);
+ break;
+ case RejectAlgorithm:
+ m_resolver->rejectInternal(value, true);
+ break;
+ }
+}
+
+void Future::appendCallbacks(PassRefPtr<FutureCallback> acceptCallback, PassRefPtr<FutureCallback> rejectCallback)
+{
+ m_acceptCallbacks.append(acceptCallback);
+
+ m_rejectCallbacks.append(rejectCallback);
+
+ if (m_state == Accepted)
+ queueProcessAcceptCallbacksTask(m_result);
+
+ if (m_state == Rejected)
+ queueProcessRejectCallbacksTask(m_result);
+}
+
+PassRefPtr<Future> Future::then(PassRefPtr<AnyCallback> acceptCallback, PassRefPtr<AnyCallback> rejectCallback)
+{
+ RefPtr<Future> newFuture = Future::create();
+
+ RefPtr<FutureResolver> newResolver = newFuture->getResolver();
+
+ FutureCallback::Algorithm algorithmForAccept = FutureCallback::AcceptAlgorithm;
+ if (acceptCallback)
+ algorithmForAccept = FutureCallback::WrapperAlgorithm;
+ RefPtr<FutureCallback> acceptFutureCallback = FutureCallback::create(algorithmForAccept, newResolver, acceptCallback);
+
+ FutureCallback::Algorithm algorithmForReject = FutureCallback::RejectAlgorithm;
+ if (rejectCallback)
+ algorithmForReject = FutureCallback::WrapperAlgorithm;
+ RefPtr<FutureCallback> rejectFutureCallback = FutureCallback::create(algorithmForReject, newResolver, rejectCallback);
+
+ appendCallbacks(acceptFutureCallback, rejectFutureCallback);
+
+ return newFuture;
+}
+
+void Future::then(PassRefPtr<Future> future)
+{
+ ScriptExecutionContext* context = getScriptExecutionContext();
+
+ RefPtr<FutureResolver> resolver = future->getResolver();
+
+ FutureCallback::Algorithm algorithmForAccept = FutureCallback::AcceptAlgorithm;
+ RefPtr<FutureCallback> acceptFutureCallback = FutureCallback::create(algorithmForAccept, resolver, 0);
+
+ FutureCallback::Algorithm algorithmForReject = FutureCallback::RejectAlgorithm;
+ RefPtr<FutureCallback> rejectFutureCallback = FutureCallback::create(algorithmForReject, resolver, 0);
+
+ appendCallbacks(acceptFutureCallback, rejectFutureCallback);
+}
+
+void Future::done(PassRefPtr<AnyCallback> acceptCallback, PassRefPtr<AnyCallback> rejectCallback)
+{
+ RefPtr<FutureCallback> acceptFutureCallback = FutureCallback::create(FutureCallback::NoAlgorithm, 0, acceptCallback);
+ RefPtr<FutureCallback> rejectFutureCallback = FutureCallback::create(FutureCallback::NoAlgorithm, 0, rejectCallback);
+ appendCallbacks(acceptFutureCallback, rejectFutureCallback);
+}
+
+void Future::processAcceptCallbacks(const ScriptValue& value)
+{
+ LOG(Network, "processAcceptCallbacks %d", refCount());
+
+ for (int i = 0; i < m_acceptCallbacks.size(); ++i)
+ m_acceptCallbacks[i]->invoke(value);
+
+ m_acceptCallbacks.clear();
+}
+
+void Future::queueProcessAcceptCallbacksTask(const ScriptValue& value)
+{
+ getScriptExecutionContext()->postTask(ProcessAcceptCallbacksTask::create(this, value));
+}
+
+void Future::processRejectCallbacks(const ScriptValue& value)
+{
+ LOG(Network, "processRejectCallbacks");
+
+ for (int i = 0; i < m_rejectCallbacks.size(); ++i)
+ m_rejectCallbacks[i]->invoke(value);
+ m_rejectCallbacks.clear();
+}
+
+void Future::queueProcessRejectCallbacksTask(const ScriptValue& value)
+{
+ getScriptExecutionContext()->postTask(ProcessRejectCallbacksTask::create(this, value));
+}
+
+} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698