Bug 882076 - C++ callbacks to DOM Promises. r=baku,mccr8

This commit is contained in:
Nikhil Marathe 2013-11-19 10:43:51 -08:00
parent 53df8db426
commit 297a29ac6d
6 changed files with 122 additions and 2 deletions

View File

@ -11,6 +11,7 @@
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/Preferences.h"
#include "PromiseCallback.h"
#include "PromiseNativeHandler.h"
#include "nsContentUtils.h"
#include "nsPIDOMWindow.h"
#include "WorkerPrivate.h"
@ -22,6 +23,8 @@
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS0(PromiseNativeHandler)
// PromiseTask
// This class processes the promise's callbacks with promise's result.
@ -379,6 +382,18 @@ Promise::Catch(const Optional<OwningNonNull<AnyCallback> >& aRejectCallback)
return Then(resolveCb, aRejectCallback);
}
void
Promise::AppendNativeHandler(PromiseNativeHandler* aRunnable)
{
nsRefPtr<PromiseCallback> resolveCb =
new NativePromiseCallback(aRunnable, Resolved);
nsRefPtr<PromiseCallback> rejectCb =
new NativePromiseCallback(aRunnable, Rejected);
AppendCallbacks(resolveCb, rejectCb);
}
void
Promise::AppendCallbacks(PromiseCallback* aResolveCallback,
PromiseCallback* aRejectCallback)

View File

@ -20,13 +20,15 @@
namespace mozilla {
namespace dom {
class PromiseInit;
class PromiseCallback;
class AnyCallback;
class PromiseCallback;
class PromiseInit;
class PromiseNativeHandler;
class Promise MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
friend class NativePromiseCallback;
friend class PromiseTask;
friend class PromiseResolverTask;
friend class ResolvePromiseCallback;
@ -78,6 +80,8 @@ public:
already_AddRefed<Promise>
Catch(const Optional<OwningNonNull<AnyCallback> >& aRejectCallback);
void AppendNativeHandler(PromiseNativeHandler* aRunnable);
private:
enum PromiseState {
Pending,

View File

@ -6,6 +6,7 @@
#include "PromiseCallback.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
namespace mozilla {
namespace dom {
@ -209,6 +210,47 @@ SimpleWrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
mCallback->Call(mPromise, aValue, rv);
}
// NativePromiseCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(NativePromiseCallback,
PromiseCallback, mHandler)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(NativePromiseCallback)
NS_INTERFACE_MAP_END_INHERITING(PromiseCallback)
NS_IMPL_ADDREF_INHERITED(NativePromiseCallback, PromiseCallback)
NS_IMPL_RELEASE_INHERITED(NativePromiseCallback, PromiseCallback)
NativePromiseCallback::NativePromiseCallback(PromiseNativeHandler* aHandler,
Promise::PromiseState aState)
: mHandler(aHandler)
, mState(aState)
{
MOZ_ASSERT(aHandler);
MOZ_COUNT_CTOR(NativePromiseCallback);
}
NativePromiseCallback::~NativePromiseCallback()
{
MOZ_COUNT_DTOR(NativePromiseCallback);
}
void
NativePromiseCallback::Call(JS::Handle<JS::Value> aValue)
{
if (mState == Promise::Resolved) {
mHandler->ResolvedCallback(aValue);
return;
}
if (mState == Promise::Rejected) {
mHandler->RejectedCallback(aValue);
return;
}
NS_NOTREACHED("huh?");
}
/* static */ PromiseCallback*
PromiseCallback::Factory(Promise* aNextPromise, AnyCallback* aCallback,
Task aTask)

View File

@ -111,6 +111,25 @@ private:
nsRefPtr<Promise> mPromise;
};
// NativePromiseCallback wraps a NativePromiseHandler.
class NativePromiseCallback MOZ_FINAL : public PromiseCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(NativePromiseCallback,
PromiseCallback)
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
NativePromiseCallback(PromiseNativeHandler* aHandler,
Promise::PromiseState aState);
~NativePromiseCallback();
private:
nsRefPtr<PromiseNativeHandler> mHandler;
Promise::PromiseState mState;
};
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,39 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PromiseNativeHandler_h
#define mozilla_dom_PromiseNativeHandler_h
#include "nsISupports.h"
namespace mozilla {
namespace dom {
/*
* PromiseNativeHandler allows C++ to react to a Promise being rejected/resolved.
* A PromiseNativeHandler can be appended to a Promise using
* Promise::AppendNativeHandler().
*/
class PromiseNativeHandler : public nsISupports
{
public:
// NS_IMPL_ISUPPORTS0 in Promise.cpp.
NS_DECL_ISUPPORTS
virtual ~PromiseNativeHandler()
{ }
virtual void
ResolvedCallback(JS::Handle<JS::Value> aValue) = 0;
virtual void
RejectedCallback(JS::Handle<JS::Value> aValue) = 0;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PromiseNativeHandler_h

View File

@ -10,6 +10,7 @@ XPIDL_MODULE = 'dom_promise'
EXPORTS.mozilla.dom += [
'Promise.h',
'PromiseNativeHandler.h'
]
SOURCES += [