mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 926091 - Make Gamepad.buttons into an array of GamepadButton objects. r=smaug
This commit is contained in:
parent
64b6f02e5c
commit
07639a841d
@ -19,7 +19,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Gamepad)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(Gamepad, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(Gamepad, mParent, mButtonsVariant)
|
||||
|
||||
Gamepad::Gamepad(nsISupports* aParent,
|
||||
const nsAString& aID, uint32_t aIndex,
|
||||
@ -29,10 +29,14 @@ Gamepad::Gamepad(nsISupports* aParent,
|
||||
mID(aID),
|
||||
mIndex(aIndex),
|
||||
mMapping(aMapping),
|
||||
mConnected(true)
|
||||
mConnected(true),
|
||||
mButtons(aNumButtons),
|
||||
mAxes(aNumAxes)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mButtons.InsertElementsAt(0, aNumButtons);
|
||||
for (unsigned i = 0; i < aNumButtons; i++) {
|
||||
mButtons.InsertElementAt(i, new GamepadButton(mParent));
|
||||
}
|
||||
mAxes.InsertElementsAt(0, aNumAxes, 0.0f);
|
||||
}
|
||||
|
||||
@ -52,8 +56,8 @@ void
|
||||
Gamepad::SetButton(uint32_t aButton, bool aPressed, double aValue)
|
||||
{
|
||||
MOZ_ASSERT(aButton < mButtons.Length());
|
||||
mButtons[aButton].pressed = aPressed;
|
||||
mButtons[aButton].value = aValue;
|
||||
mButtons[aButton]->SetPressed(aPressed);
|
||||
mButtons[aButton]->SetValue(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
@ -66,6 +70,11 @@ Gamepad::SetAxis(uint32_t aAxis, double aValue)
|
||||
nsresult
|
||||
Gamepad::GetButtons(nsIVariant** aButtons)
|
||||
{
|
||||
if (mButtonsVariant) {
|
||||
NS_ADDREF(*aButtons = mButtonsVariant);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsVariant> out = new nsVariant();
|
||||
NS_ENSURE_STATE(out);
|
||||
|
||||
@ -74,15 +83,15 @@ Gamepad::GetButtons(nsIVariant** aButtons)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// Note: The resulting nsIVariant dupes both the array and its elements.
|
||||
double* array = reinterpret_cast<double*>
|
||||
(NS_Alloc(mButtons.Length() * sizeof(double)));
|
||||
GamepadButton** array = reinterpret_cast<GamepadButton**>
|
||||
(NS_Alloc(mButtons.Length() * sizeof(GamepadButton*)));
|
||||
NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (uint32_t i = 0; i < mButtons.Length(); ++i) {
|
||||
array[i] = mButtons[i].value;
|
||||
array[i] = mButtons[i].get();
|
||||
}
|
||||
|
||||
nsresult rv = out->SetAsArray(nsIDataType::VTYPE_DOUBLE,
|
||||
nsresult rv = out->SetAsArray(nsIDataType::VTYPE_INTERFACE,
|
||||
nullptr,
|
||||
mButtons.Length(),
|
||||
reinterpret_cast<void*>(array));
|
||||
@ -90,6 +99,7 @@ Gamepad::GetButtons(nsIVariant** aButtons)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mButtonsVariant = out;
|
||||
*aButtons = out.forget().get();
|
||||
return NS_OK;
|
||||
}
|
||||
@ -135,7 +145,8 @@ Gamepad::SyncState(Gamepad* aOther)
|
||||
|
||||
mConnected = aOther->mConnected;
|
||||
for (uint32_t i = 0; i < mButtons.Length(); ++i) {
|
||||
mButtons[i] = aOther->mButtons[i];
|
||||
mButtons[i]->SetPressed(aOther->mButtons[i]->Pressed());
|
||||
mButtons[i]->SetValue(aOther->mButtons[i]->Value());
|
||||
}
|
||||
for (uint32_t i = 0; i < mAxes.Length(); ++i) {
|
||||
mAxes[i] = aOther->mAxes[i];
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define mozilla_dom_gamepad_Gamepad_h
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/GamepadButton.h"
|
||||
#include <stdint.h>
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIVariant.h"
|
||||
@ -22,16 +23,6 @@ enum GamepadMappingType
|
||||
StandardMapping = 1
|
||||
};
|
||||
|
||||
// TODO: fix the spec to expose both pressed and value:
|
||||
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21388
|
||||
struct GamepadButton
|
||||
{
|
||||
bool pressed;
|
||||
double value;
|
||||
|
||||
GamepadButton(): pressed(false), value(0.0) {}
|
||||
};
|
||||
|
||||
class Gamepad : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
@ -119,8 +110,11 @@ protected:
|
||||
bool mConnected;
|
||||
|
||||
// Current state of buttons, axes.
|
||||
nsTArray<GamepadButton> mButtons;
|
||||
nsTArray<nsRefPtr<GamepadButton>> mButtons;
|
||||
nsTArray<double> mAxes;
|
||||
|
||||
// Cached variant array.
|
||||
nsCOMPtr<nsIVariant> mButtonsVariant;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
28
dom/gamepad/GamepadButton.cpp
Normal file
28
dom/gamepad/GamepadButton.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/* 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 "mozilla/dom/GamepadButton.h"
|
||||
#include "mozilla/dom/GamepadBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(GamepadButton)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(GamepadButton)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GamepadButton)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(GamepadButton, mParent)
|
||||
|
||||
/* virtual */ JSObject*
|
||||
GamepadButton::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||
{
|
||||
return GamepadButtonBinding::Wrap(aCx, aScope, this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
69
dom/gamepad/GamepadButton.h
Normal file
69
dom/gamepad/GamepadButton.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* 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_gamepad_GamepadButton_h
|
||||
#define mozilla_dom_gamepad_GamepadButton_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class GamepadButton : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
GamepadButton(nsISupports* aParent) : mParent(aParent),
|
||||
mPressed(false),
|
||||
mValue(0)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GamepadButton)
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
void SetPressed(bool aPressed)
|
||||
{
|
||||
mPressed = aPressed;
|
||||
}
|
||||
|
||||
void SetValue(double aValue)
|
||||
{
|
||||
mValue = aValue;
|
||||
}
|
||||
|
||||
bool Pressed() const
|
||||
{
|
||||
return mPressed;
|
||||
}
|
||||
|
||||
double Value() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~GamepadButton() {}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
bool mPressed;
|
||||
double mValue;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_gamepad_GamepadButton_h
|
@ -6,11 +6,13 @@
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'Gamepad.h',
|
||||
'GamepadButton.h',
|
||||
'GamepadService.h',
|
||||
]
|
||||
|
||||
CPP_SOURCES = [
|
||||
'Gamepad.cpp',
|
||||
'GamepadButton.cpp',
|
||||
'GamepadService.cpp',
|
||||
]
|
||||
|
||||
|
@ -47,8 +47,8 @@ var tests = [
|
||||
|
||||
function check_button_pressed() {
|
||||
// At this point the both frames should see the button as pressed.
|
||||
is(f1.contentWindow.gamepad.buttons[0], 1, "frame 1 sees button pressed");
|
||||
is(f2.contentWindow.gamepad.buttons[0], 1, "frame 2 sees button pressed");
|
||||
ok(f1.contentWindow.gamepad.buttons[0].pressed, "frame 1 sees button pressed");
|
||||
ok(f2.contentWindow.gamepad.buttons[0].pressed, "frame 2 sees button pressed");
|
||||
|
||||
// Now release the button, then hide the second frame.
|
||||
GamepadService.newButtonEvent(index, 0, false);
|
||||
@ -64,15 +64,15 @@ function check_second_frame_no_button_press () {
|
||||
* At this point the first frame should see the button as pressed,
|
||||
* but the second frame should not, since it's hidden.
|
||||
*/
|
||||
is(f1.contentWindow.gamepad.buttons[0], 1, "frame 1 sees button pressed");
|
||||
is(f2.contentWindow.gamepad.buttons[0], 0, "frame 2 should not see button pressed");
|
||||
ok(f1.contentWindow.gamepad.buttons[0].pressed, "frame 1 sees button pressed");
|
||||
ok(!f2.contentWindow.gamepad.buttons[0].pressed, "frame 2 should not see button pressed");
|
||||
|
||||
// Now unhide the second frame.
|
||||
setFrameVisible(f2, true);
|
||||
SpecialPowers.executeSoon(function() {
|
||||
// Now that the frame is visible again, it should see the button
|
||||
// that was pressed.
|
||||
is(f2.contentWindow.gamepad.buttons[0], 1, "frame 2 sees button pressed");
|
||||
ok(f2.contentWindow.gamepad.buttons[0].pressed, "frame 2 sees button pressed");
|
||||
// cleanup
|
||||
GamepadService.removeGamepad(index);
|
||||
SimpleTest.finish();
|
||||
|
@ -202,6 +202,7 @@ var interfaceNamesInGlobalScope =
|
||||
{name: "Gamepad", desktop: true},
|
||||
{name: "GamepadAxisMoveEvent", desktop: true},
|
||||
{name: "GamepadButtonEvent", desktop: true},
|
||||
{name: "GamepadButton", desktop: true},
|
||||
{name: "GamepadEvent", desktop: true},
|
||||
"HashChangeEvent",
|
||||
"History",
|
||||
|
@ -5,6 +5,12 @@
|
||||
|
||||
interface nsIVariant;
|
||||
|
||||
[Pref="dom.gamepad.enabled"]
|
||||
interface GamepadButton {
|
||||
readonly attribute boolean pressed;
|
||||
readonly attribute double value;
|
||||
};
|
||||
|
||||
[Pref="dom.gamepad.enabled"]
|
||||
interface Gamepad {
|
||||
/**
|
||||
@ -31,7 +37,7 @@ interface Gamepad {
|
||||
|
||||
/**
|
||||
* The current state of all buttons on the device, an
|
||||
* array of doubles.
|
||||
* array of GamepadButton.
|
||||
*/
|
||||
[Throws]
|
||||
readonly attribute nsIVariant buttons;
|
||||
|
Loading…
Reference in New Issue
Block a user