bug 851542 - Gamepad to webidl (with nsIVariant). r=smaug
--- a/content/events/src/nsDOMGamepad.cpp
+++ b/content/events/src/nsDOMGamepad.cpp
@@ -1,56 +1,46 @@
/* 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/. */
#include "nsDOMGamepad.h"
-#include "nsDOMClassInfoID.h"
-#include "nsIClassInfo.h"
-#include "nsIXPCScriptable.h"
+#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsContentUtils.h"
#include "nsVariant.h"
+#include "mozilla/dom/GamepadBinding.h"
-DOMCI_DATA(Gamepad, nsDOMGamepad)
+using namespace mozilla;
+using namespace mozilla::dom;
-NS_IMPL_ADDREF(nsDOMGamepad)
-NS_IMPL_RELEASE(nsDOMGamepad)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMGamepad)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMGamepad)
-NS_INTERFACE_MAP_BEGIN(nsDOMGamepad)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMGamepad)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIDOMGamepad)
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Gamepad)
NS_INTERFACE_MAP_END
-nsDOMGamepad::nsDOMGamepad(const nsAString& aID, uint32_t aIndex,
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsDOMGamepad, mParent)
+
+nsDOMGamepad::nsDOMGamepad(nsISupports* aParent,
+ const nsAString& aID, uint32_t aIndex,
uint32_t aNumButtons, uint32_t aNumAxes)
- : mID(aID),
+ : mParent(aParent),
+ mID(aID),
mIndex(aIndex),
mConnected(true)
{
+ SetIsDOMBinding();
mButtons.InsertElementsAt(0, aNumButtons, 0);
mAxes.InsertElementsAt(0, aNumAxes, 0.0f);
}
-/* readonly attribute DOMString id; */
-NS_IMETHODIMP
-nsDOMGamepad::GetId(nsAString& aID)
-{
- aID = mID;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMGamepad::GetIndex(uint32_t* aIndex)
-{
- *aIndex = mIndex;
- return NS_OK;
-}
-
void
nsDOMGamepad::SetIndex(uint32_t aIndex)
{
mIndex = aIndex;
}
void
nsDOMGamepad::SetConnected(bool aConnected)
@@ -67,26 +57,17 @@ nsDOMGamepad::SetButton(uint32_t aButton
void
nsDOMGamepad::SetAxis(uint32_t aAxis, double aValue)
{
MOZ_ASSERT(aAxis < mAxes.Length());
mAxes[aAxis] = aValue;
}
-/* readonly attribute boolean connected; */
-NS_IMETHODIMP
-nsDOMGamepad::GetConnected(bool* aConnected)
-{
- *aConnected = mConnected;
- return NS_OK;
-}
-
-/* readonly attribute nsIVariant buttons; */
-NS_IMETHODIMP
+nsresult
nsDOMGamepad::GetButtons(nsIVariant** aButtons)
{
nsRefPtr<nsVariant> out = new nsVariant();
NS_ENSURE_STATE(out);
if (mButtons.Length() == 0) {
nsresult rv = out->SetAsEmptyArray();
NS_ENSURE_SUCCESS(rv, rv);
@@ -107,18 +88,17 @@ nsDOMGamepad::GetButtons(nsIVariant** aB
NS_Free(array);
NS_ENSURE_SUCCESS(rv, rv);
}
*aButtons = out.forget().get();
return NS_OK;
}
-/* readonly attribute nsIVariant axes; */
-NS_IMETHODIMP
+nsresult
nsDOMGamepad::GetAxes(nsIVariant** aAxes)
{
nsRefPtr<nsVariant> out = new nsVariant();
NS_ENSURE_STATE(out);
if (mAxes.Length() == 0) {
nsresult rv = out->SetAsEmptyArray();
NS_ENSURE_SUCCESS(rv, rv);
@@ -157,15 +137,21 @@ nsDOMGamepad::SyncState(nsDOMGamepad* aO
mButtons[i] = aOther->mButtons[i];
}
for (uint32_t i = 0; i < mAxes.Length(); ++i) {
mAxes[i] = aOther->mAxes[i];
}
}
already_AddRefed<nsDOMGamepad>
-nsDOMGamepad::Clone()
+nsDOMGamepad::Clone(nsISupports* aParent)
{
nsRefPtr<nsDOMGamepad> out =
- new nsDOMGamepad(mID, mIndex, mButtons.Length(), mAxes.Length());
+ new nsDOMGamepad(aParent, mID, mIndex, mButtons.Length(), mAxes.Length());
out->SyncState(this);
return out.forget();
}
+
+/* virtual */ JSObject*
+nsDOMGamepad::WrapObject(JSContext* aCx, JSObject* aScope)
+{
+ return GamepadBinding::Wrap(aCx, aScope, this);
+}
--- a/content/events/src/nsDOMGamepad.h
+++ b/content/events/src/nsDOMGamepad.h
@@ -1,45 +1,91 @@
/* 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 nsDomGamepad_h
#define nsDomGamepad_h
+#include "mozilla/ErrorResult.h"
#include "mozilla/StandardInteger.h"
+#include "nsCOMPtr.h"
#include "nsIDOMGamepad.h"
#include "nsString.h"
-#include "nsCOMPtr.h"
#include "nsTArray.h"
+#include "nsWrapperCache.h"
class nsDOMGamepad : public nsIDOMGamepad
+ , public nsWrapperCache
{
public:
- nsDOMGamepad(const nsAString& aID, uint32_t aIndex,
+ nsDOMGamepad(nsISupports* aParent,
+ const nsAString& aID, uint32_t aIndex,
uint32_t aNumButtons, uint32_t aNumAxes);
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDOMGAMEPAD
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMGamepad)
nsDOMGamepad();
void SetConnected(bool aConnected);
void SetButton(uint32_t aButton, double aValue);
void SetAxis(uint32_t aAxis, double aValue);
void SetIndex(uint32_t aIndex);
// Make the state of this gamepad equivalent to other.
void SyncState(nsDOMGamepad* other);
- // Return a new nsDOMGamepad containing the same data as this object.
- already_AddRefed<nsDOMGamepad> Clone();
+ // Return a new nsDOMGamepad containing the same data as this object,
+ // parented to aParent.
+ already_AddRefed<nsDOMGamepad> Clone(nsISupports* aParent);
+
+ nsISupports* GetParentObject() const
+ {
+ return mParent;
+ }
+
+ virtual JSObject*
+ WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
+
+ void GetId(nsAString& aID) const
+ {
+ aID = mID;
+ }
+
+ bool Connected() const
+ {
+ return mConnected;
+ }
+
+ uint32_t Index() const
+ {
+ return mIndex;
+ }
+
+ already_AddRefed<nsIVariant> GetButtons(mozilla::ErrorResult& aRv)
+ {
+ nsCOMPtr<nsIVariant> buttons;
+ aRv = GetButtons(getter_AddRefs(buttons));
+ return buttons.forget();
+ }
+
+ already_AddRefed<nsIVariant> GetAxes(mozilla::ErrorResult& aRv)
+ {
+ nsCOMPtr<nsIVariant> axes;
+ aRv = GetAxes(getter_AddRefs(axes));
+ return axes.forget();
+ }
private:
virtual ~nsDOMGamepad() {}
+ nsresult GetButtons(nsIVariant** aButtons);
+ nsresult GetAxes(nsIVariant** aAxes);
+
protected:
+ nsCOMPtr<nsISupports> mParent;
nsString mID;
uint32_t mIndex;
// true if this gamepad is currently connected.
bool mConnected;
// Current state of buttons, axes.
nsTArray<double> mButtons;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -213,19 +213,16 @@
#include "nsIDOMCRMFObject.h"
#include "nsIDOMCryptoLegacy.h"
#else
#include "nsIDOMCrypto.h"
#endif
#include "nsIControllers.h"
#include "nsISelection.h"
#include "nsIBoxObject.h"
-#ifdef MOZ_GAMEPAD
-#include "nsIDOMGamepad.h"
-#endif
#ifdef MOZ_XUL
#include "nsITreeSelection.h"
#include "nsITreeContentView.h"
#include "nsITreeView.h"
#include "nsIXULTemplateBuilder.h"
#include "nsTreeColumns.h"
#endif
#include "nsIDOMXPathExpression.h"
@@ -968,21 +965,16 @@ static nsDOMClassInfoData sClassInfoData
NS_DEFINE_CLASSINFO_DATA(Touch, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(TouchList, nsDOMTouchListSH,
ARRAY_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(TouchEvent, nsEventSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
-#ifdef MOZ_GAMEPAD
- NS_DEFINE_CLASSINFO_DATA(Gamepad, nsDOMGenericSH,
- DOM_DEFAULT_SCRIPTABLE_FLAGS)
-#endif
-
NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframeRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -2469,22 +2461,16 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_MAYBE_DISABLE(TouchEvent, nsIDOMTouchEvent,
!nsDOMTouchEvent::PrefEnabled())
DOM_CLASSINFO_MAP_ENTRY(nsIDOMTouchEvent)
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
-#ifdef MOZ_GAMEPAD
- DOM_CLASSINFO_MAP_BEGIN(Gamepad, nsIDOMGamepad)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMGamepad)
- DOM_CLASSINFO_MAP_END
-#endif
-
DOM_CLASSINFO_MAP_BEGIN(MozCSSKeyframeRule, nsIDOMMozCSSKeyframeRule)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframeRule)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozCSSKeyframesRule, nsIDOMMozCSSKeyframesRule)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframesRule)
DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -233,20 +233,16 @@ DOMCI_CLASS(IDBKeyRange)
DOMCI_CLASS(IDBIndex)
DOMCI_CLASS(IDBVersionChangeEvent)
DOMCI_CLASS(IDBOpenDBRequest)
DOMCI_CLASS(Touch)
DOMCI_CLASS(TouchList)
DOMCI_CLASS(TouchEvent)
-#ifdef MOZ_GAMEPAD
-DOMCI_CLASS(Gamepad)
-#endif
-
DOMCI_CLASS(MozCSSKeyframeRule)
DOMCI_CLASS(MozCSSKeyframesRule)
DOMCI_CLASS(CSSPageRule)
DOMCI_CLASS(MediaQueryList)
#ifdef MOZ_B2G_RIL
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1484,16 +1484,20 @@ nsGlobalWindow::FreeInnerObjects()
NotifyWindowIDDestroyed("inner-window-destroyed");
CleanupCachedXBLHandlers(this);
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
mAudioContexts[i]->Shutdown();
}
mAudioContexts.Clear();
+
+#ifdef MOZ_GAMEPAD
+ mGamepads.Clear();
+#endif
}
//*****************************************************************************
// nsGlobalWindow::nsISupports
//*****************************************************************************
#define OUTER_WINDOW_ONLY \
if (IsOuterWindow()) {
@@ -1626,16 +1630,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStorage)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplicationCache)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIdleService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingStorageEvents)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIdleObservers)
+#ifdef MOZ_GAMEPAD
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepads)
+#endif
+
// Traverse stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioContexts)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -1669,16 +1677,20 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mApplicationCache)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleService)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingStorageEvents)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleObservers)
+#ifdef MOZ_GAMEPAD
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)
+#endif
+
// Unlink stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioContexts)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -362,16 +362,20 @@ DOMInterfaces = {
'nativeType': 'JSObject'
}],
'GainNode': {
'resultNotAddRefed': [ 'gain' ],
'wrapperCache': False
},
+'Gamepad': {
+ 'nativeType': 'nsDOMGamepad',
+},
+
'HTMLAppletElement': {
'nativeType': 'mozilla::dom::HTMLSharedObjectElement'
},
'HTMLBaseElement': {
'nativeType': 'mozilla::dom::HTMLSharedElement'
},
@@ -1453,16 +1457,17 @@ addExternalIface('MozRDFCompositeDataSou
notflattened=True)
addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
addExternalIface('MozNamedAttrMap')
addExternalIface('nsIControllers', nativeType='nsIControllers')
addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
addExternalIface('nsISupports', nativeType='nsISupports')
addExternalIface('nsIEditor', nativeType='nsIEditor', notflattened=True)
+addExternalIface('nsIVariant', nativeType='nsIVariant', notflattened=True)
addExternalIface('OutputStream', nativeType='nsIOutputStream',
notflattened=True)
addExternalIface('Principal', nativeType='nsIPrincipal',
headerFile='nsIPrincipal.h', notflattened=True)
addExternalIface('Selection', nativeType='nsISelection')
addExternalIface('StyleSheetList')
addExternalIface('SVGAnimatedEnumeration', headerFile='nsIDOMSVGAnimatedEnum.h')
addExternalIface('SVGAnimatedNumber')
--- a/dom/interfaces/gamepad/nsIDOMGamepad.idl
+++ b/dom/interfaces/gamepad/nsIDOMGamepad.idl
@@ -4,36 +4,9 @@
#include "nsISupports.idl"
interface nsIVariant;
[builtinclass, scriptable, uuid(ff13acd9-11da-4817-8f2a-4a5700dfd13e)]
interface nsIDOMGamepad : nsISupports
{
- /**
- * An identifier, unique per type of device.
- */
- readonly attribute DOMString id;
-
- /**
- * The game port index for the device. Unique per device
- * attached to this system.
- */
- readonly attribute unsigned long index;
-
- /**
- * true if this gamepad is currently connected to the system.
- */
- readonly attribute boolean connected;
-
- /**
- * The current state of all buttons on the device, an
- * array of doubles.
- */
- readonly attribute nsIVariant buttons;
-
- /**
- * The current position of all axes on the device, an
- * array of doubles.
- */
- readonly attribute nsIVariant axes;
};
--- a/dom/system/GamepadService.cpp
+++ b/dom/system/GamepadService.cpp
@@ -128,17 +128,18 @@ GamepadService::RemoveListener(nsGlobalW
uint32_t
GamepadService::AddGamepad(const char* aId,
uint32_t aNumButtons,
uint32_t aNumAxes)
{
//TODO: bug 852258: get initial button/axis state
nsRefPtr<nsDOMGamepad> gamepad =
- new nsDOMGamepad(NS_ConvertUTF8toUTF16(nsDependentCString(aId)),
+ new nsDOMGamepad(nullptr,
+ NS_ConvertUTF8toUTF16(nsDependentCString(aId)),
0,
aNumButtons,
aNumAxes);
int index = -1;
for (uint32_t i = 0; i < mGamepads.Length(); i++) {
if (!mGamepads[i]) {
mGamepads[i] = gamepad;
index = i;
@@ -408,17 +409,18 @@ GamepadService::SetWindowHasSeenGamepad(
{
if (mListeners.IndexOf(aWindow) == NoIndex) {
// This window isn't even listening for gamepad events.
return;
}
if (aHasSeen) {
aWindow->SetHasSeenGamepadInput(true);
- nsRefPtr<nsDOMGamepad> gamepad = mGamepads[aIndex]->Clone();
+ nsCOMPtr<nsISupports> window = nsGlobalWindow::ToSupports(aWindow);
+ nsRefPtr<nsDOMGamepad> gamepad = mGamepads[aIndex]->Clone(window);
aWindow->AddGamepad(aIndex, gamepad);
} else {
aWindow->RemoveGamepad(aIndex);
}
}
// static
void
new file mode 100644
--- /dev/null
+++ b/dom/webidl/Gamepad.webidl
@@ -0,0 +1,37 @@
+/* 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/. */
+
+interface nsIVariant;
+
+interface Gamepad {
+ /**
+ * An identifier, unique per type of device.
+ */
+ readonly attribute DOMString id;
+
+ /**
+ * The game port index for the device. Unique per device
+ * attached to this system.
+ */
+ readonly attribute unsigned long index;
+
+ /**
+ * true if this gamepad is currently connected to the system.
+ */
+ readonly attribute boolean connected;
+
+ /**
+ * The current state of all buttons on the device, an
+ * array of doubles.
+ */
+ [Throws]
+ readonly attribute nsIVariant buttons;
+
+ /**
+ * The current position of all axes on the device, an
+ * array of doubles.
+ */
+ [Throws]
+ readonly attribute nsIVariant axes;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -66,16 +66,17 @@ webidl_files = \
File.webidl \
FileHandle.webidl \
FileList.webidl \
FileReaderSync.webidl \
FileRequest.webidl \
FormData.webidl \
Function.webidl \
GainNode.webidl \
+ Gamepad.webidl \
HTMLAnchorElement.webidl \
HTMLAppletElement.webidl \
HTMLAreaElement.webidl \
HTMLAudioElement.webidl \
HTMLBaseElement.webidl \
HTMLBodyElement.webidl \
HTMLBRElement.webidl \
HTMLButtonElement.webidl \