Bug 947241. Make Gamepad used cached sequences for its buttons and axes. r=ted,peterv

This commit is contained in:
Boris Zbarsky 2013-12-06 11:41:13 -05:00
parent 0e8c9f6887
commit 0641816139
3 changed files with 17 additions and 90 deletions

View File

@ -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_2(Gamepad, mParent, mButtonsVariant)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(Gamepad, mParent, mButtons)
Gamepad::Gamepad(nsISupports* aParent,
const nsAString& aID, uint32_t aIndex,
@ -64,75 +64,10 @@ void
Gamepad::SetAxis(uint32_t aAxis, double aValue)
{
MOZ_ASSERT(aAxis < mAxes.Length());
mAxes[aAxis] = aValue;
}
nsresult
Gamepad::GetButtons(nsIVariant** aButtons)
{
if (mButtonsVariant) {
NS_ADDREF(*aButtons = mButtonsVariant);
return NS_OK;
if (mAxes[aAxis] != aValue) {
mAxes[aAxis] = aValue;
GamepadBinding::ClearCachedAxesValue(this);
}
nsRefPtr<nsVariant> out = new nsVariant();
NS_ENSURE_STATE(out);
if (mButtons.Length() == 0) {
nsresult rv = out->SetAsEmptyArray();
NS_ENSURE_SUCCESS(rv, rv);
} else {
// Note: The resulting nsIVariant dupes both the array and its elements.
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].get();
}
nsresult rv = out->SetAsArray(nsIDataType::VTYPE_INTERFACE,
nullptr,
mButtons.Length(),
reinterpret_cast<void*>(array));
NS_Free(array);
NS_ENSURE_SUCCESS(rv, rv);
}
mButtonsVariant = out;
*aButtons = out.forget().get();
return NS_OK;
}
nsresult
Gamepad::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);
} else {
// Note: The resulting nsIVariant dupes both the array and its elements.
double* array = reinterpret_cast<double*>
(NS_Alloc(mAxes.Length() * sizeof(double)));
NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
for (uint32_t i = 0; i < mAxes.Length(); ++i) {
array[i] = mAxes[i];
}
nsresult rv = out->SetAsArray(nsIDataType::VTYPE_DOUBLE,
nullptr,
mAxes.Length(),
reinterpret_cast<void*>(array));
NS_Free(array);
NS_ENSURE_SUCCESS(rv, rv);
}
*aAxes = out.forget().get();
return NS_OK;
}
void
@ -148,9 +83,14 @@ Gamepad::SyncState(Gamepad* aOther)
mButtons[i]->SetPressed(aOther->mButtons[i]->Pressed());
mButtons[i]->SetValue(aOther->mButtons[i]->Value());
}
bool changed = false;
for (uint32_t i = 0; i < mAxes.Length(); ++i) {
changed = changed || (mAxes[i] != aOther->mAxes[i]);
mAxes[i] = aOther->mAxes[i];
}
if (changed) {
GamepadBinding::ClearCachedAxesValue(this);
}
}
already_AddRefed<Gamepad>

View File

@ -9,7 +9,6 @@
#include "mozilla/dom/GamepadButton.h"
#include <stdint.h>
#include "nsCOMPtr.h"
#include "nsIVariant.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
@ -78,26 +77,19 @@ public:
return mIndex;
}
already_AddRefed<nsIVariant> GetButtons(mozilla::ErrorResult& aRv)
void GetButtons(nsTArray<nsRefPtr<GamepadButton>>& aButtons) const
{
nsCOMPtr<nsIVariant> buttons;
aRv = GetButtons(getter_AddRefs(buttons));
return buttons.forget();
aButtons = mButtons;
}
already_AddRefed<nsIVariant> GetAxes(mozilla::ErrorResult& aRv)
void GetAxes(nsTArray<double>& aAxes) const
{
nsCOMPtr<nsIVariant> axes;
aRv = GetAxes(getter_AddRefs(axes));
return axes.forget();
aAxes = mAxes;
}
private:
virtual ~Gamepad() {}
nsresult GetButtons(nsIVariant** aButtons);
nsresult GetAxes(nsIVariant** aAxes);
protected:
nsCOMPtr<nsISupports> mParent;
nsString mID;
@ -112,9 +104,6 @@ protected:
// Current state of buttons, axes.
nsTArray<nsRefPtr<GamepadButton>> mButtons;
nsTArray<double> mAxes;
// Cached variant array.
nsCOMPtr<nsIVariant> mButtonsVariant;
};
} // namespace dom

View File

@ -3,8 +3,6 @@
* 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;
[Pref="dom.gamepad.enabled"]
interface GamepadButton {
readonly attribute boolean pressed;
@ -39,13 +37,13 @@ interface Gamepad {
* The current state of all buttons on the device, an
* array of GamepadButton.
*/
[Throws]
readonly attribute nsIVariant buttons;
[Pure, Cached]
readonly attribute sequence<GamepadButton> buttons;
/**
* The current position of all axes on the device, an
* array of doubles.
*/
[Throws]
readonly attribute nsIVariant axes;
[Pure, Cached]
readonly attribute sequence<double> axes;
};