Skip to content

Commit fc365d0

Browse files
committed
Bug 1523351 - Part 1: GamepadTouch and GamepadLightIndicator WebAPI implementation. r=baku
Differential Revision: https://phabricator.services.mozilla.com/D20744 --HG-- extra : moz-landing-system : lando
1 parent 0771ce1 commit fc365d0

15 files changed

+462
-9
lines changed

dom/gamepad/Gamepad.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Gamepad)
2222
NS_INTERFACE_MAP_END
2323

2424
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Gamepad, mParent, mButtons, mPose,
25-
mHapticActuators)
25+
mHapticActuators, mLightIndicators,
26+
mTouchEvents)
2627

2728
void Gamepad::UpdateTimestamp() {
2829
nsCOMPtr<nsPIDOMWindowInner> newWindow(do_QueryInterface(mParent));
@@ -37,12 +38,14 @@ void Gamepad::UpdateTimestamp() {
3738
Gamepad::Gamepad(nsISupports* aParent, const nsAString& aID, uint32_t aIndex,
3839
uint32_t aHashKey, GamepadMappingType aMapping,
3940
GamepadHand aHand, uint32_t aDisplayID, uint32_t aNumButtons,
40-
uint32_t aNumAxes, uint32_t aNumHaptics)
41+
uint32_t aNumAxes, uint32_t aNumHaptics,
42+
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents)
4143
: mParent(aParent),
4244
mID(aID),
4345
mIndex(aIndex),
4446
mHashKey(aHashKey),
4547
mDisplayId(aDisplayID),
48+
mTouchIdHashValue(0),
4649
mMapping(aMapping),
4750
mHand(aHand),
4851
mConnected(true),
@@ -58,6 +61,14 @@ Gamepad::Gamepad(nsISupports* aParent, const nsAString& aID, uint32_t aIndex,
5861
mHapticActuators.AppendElement(
5962
new GamepadHapticActuator(mParent, mHashKey, i));
6063
}
64+
for (uint32_t i = 0; i < aNumLightIndicator; ++i) {
65+
mLightIndicators.AppendElement(
66+
new GamepadLightIndicator(mParent, mHashKey, i));
67+
}
68+
for (uint32_t i = 0; i < aNumTouchEvents; ++i) {
69+
mTouchEvents.AppendElement(new GamepadTouch(mParent));
70+
}
71+
6172
UpdateTimestamp();
6273
}
6374

@@ -88,11 +99,35 @@ void Gamepad::SetPose(const GamepadPoseState& aPose) {
8899
UpdateTimestamp();
89100
}
90101

102+
void Gamepad::SetLightIndicatorType(uint32_t aLightIndex,
103+
GamepadLightIndicatorType aType) {
104+
mLightIndicators[aLightIndex]->SetType(aType);
105+
UpdateTimestamp();
106+
}
107+
108+
void Gamepad::SetTouchEvent(uint32_t aTouchIndex,
109+
const GamepadTouchState& aTouch) {
110+
if (aTouchIndex >= mTouchEvents.Length()) {
111+
MOZ_CRASH("Touch index exceeds the event array.");
112+
return;
113+
}
114+
115+
// Handling cross-origin tracking.
116+
GamepadTouchState touchState(aTouch);
117+
if (auto hashValue = mTouchIdHash.GetValue(touchState.touchId)) {
118+
touchState.touchId = *hashValue;
119+
} else {
120+
touchState.touchId = mTouchIdHashValue;
121+
mTouchIdHash.Put(aTouch.touchId, mTouchIdHashValue);
122+
++mTouchIdHashValue;
123+
}
124+
mTouchEvents[aTouchIndex]->SetTouchState(touchState);
125+
UpdateTimestamp();
126+
}
127+
91128
void Gamepad::SetHand(GamepadHand aHand) { mHand = aHand; }
92129

93130
void Gamepad::SyncState(Gamepad* aOther) {
94-
const char* kGamepadExtEnabledPref = "dom.gamepad.extensions.enabled";
95-
96131
if (mButtons.Length() != aOther->mButtons.Length() ||
97132
mAxes.Length() != aOther->mAxes.Length()) {
98133
return;
@@ -114,13 +149,24 @@ void Gamepad::SyncState(Gamepad* aOther) {
114149
Gamepad_Binding::ClearCachedAxesValue(this);
115150
}
116151

117-
if (Preferences::GetBool(kGamepadExtEnabledPref)) {
152+
if (StaticPrefs::dom_gamepad_extensions_enabled()) {
118153
MOZ_ASSERT(aOther->GetPose());
119154
mPose->SetPoseState(aOther->GetPose()->GetPoseState());
120155
mHand = aOther->Hand();
121156
for (uint32_t i = 0; i < mHapticActuators.Length(); ++i) {
122157
mHapticActuators[i]->Set(aOther->mHapticActuators[i]);
123158
}
159+
160+
if (StaticPrefs::dom_gamepad_extensions_lightindicator()) {
161+
for (uint32_t i = 0; i < mLightIndicators.Length(); ++i) {
162+
mLightIndicators[i]->Set(aOther->mLightIndicators[i]);
163+
}
164+
}
165+
if (StaticPrefs::dom_gamepad_extensions_multitouch()) {
166+
for (uint32_t i = 0; i < mTouchEvents.Length(); ++i) {
167+
mTouchEvents[i]->Set(aOther->mTouchEvents[i]);
168+
}
169+
}
124170
}
125171

126172
UpdateTimestamp();
@@ -129,7 +175,8 @@ void Gamepad::SyncState(Gamepad* aOther) {
129175
already_AddRefed<Gamepad> Gamepad::Clone(nsISupports* aParent) {
130176
RefPtr<Gamepad> out =
131177
new Gamepad(aParent, mID, mIndex, mHashKey, mMapping, mHand, mDisplayId,
132-
mButtons.Length(), mAxes.Length(), mHapticActuators.Length());
178+
mButtons.Length(), mAxes.Length(), mHapticActuators.Length(),
179+
mLightIndicators.Length(), mTouchEvents.Length());
133180
out->SyncState(this);
134181
return out.forget();
135182
}

dom/gamepad/Gamepad.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "mozilla/dom/GamepadButton.h"
1313
#include "mozilla/dom/GamepadPose.h"
1414
#include "mozilla/dom/GamepadHapticActuator.h"
15+
#include "mozilla/dom/GamepadLightIndicator.h"
16+
#include "mozilla/dom/GamepadTouch.h"
1517
#include "mozilla/dom/Performance.h"
1618
#include <stdint.h>
1719
#include "nsCOMPtr.h"
@@ -40,7 +42,8 @@ class Gamepad final : public nsISupports, public nsWrapperCache {
4042
Gamepad(nsISupports* aParent, const nsAString& aID, uint32_t aIndex,
4143
uint32_t aHashKey, GamepadMappingType aMapping, GamepadHand aHand,
4244
uint32_t aDisplayID, uint32_t aNumButtons, uint32_t aNumAxes,
43-
uint32_t aNumHaptics);
45+
uint32_t aNumHaptics, uint32_t aNumLightIndicator,
46+
uint32_t aNumTouchEvents);
4447

4548
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
4649
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Gamepad)
@@ -50,6 +53,9 @@ class Gamepad final : public nsISupports, public nsWrapperCache {
5053
void SetAxis(uint32_t aAxis, double aValue);
5154
void SetIndex(uint32_t aIndex);
5255
void SetPose(const GamepadPoseState& aPose);
56+
void SetLightIndicatorType(uint32_t aLightIndex,
57+
GamepadLightIndicatorType aType);
58+
void SetTouchEvent(uint32_t aTouchIndex, const GamepadTouchState& aTouch);
5359
void SetHand(GamepadHand aHand);
5460

5561
// Make the state of this gamepad equivalent to other.
@@ -93,6 +99,15 @@ class Gamepad final : public nsISupports, public nsWrapperCache {
9399
aHapticActuators = mHapticActuators;
94100
}
95101

102+
void GetLightIndicators(
103+
nsTArray<RefPtr<GamepadLightIndicator>>& aLightIndicators) const {
104+
aLightIndicators = mLightIndicators;
105+
}
106+
107+
void GetTouchEvents(nsTArray<RefPtr<GamepadTouch>>& aTouchEvents) const {
108+
aTouchEvents = mTouchEvents;
109+
}
110+
96111
private:
97112
virtual ~Gamepad() {}
98113
void UpdateTimestamp();
@@ -104,6 +119,7 @@ class Gamepad final : public nsISupports, public nsWrapperCache {
104119
// the gamepad hash key in GamepadManager
105120
uint32_t mHashKey;
106121
uint32_t mDisplayId;
122+
uint32_t mTouchIdHashValue;
107123
// The mapping in use.
108124
GamepadMappingType mMapping;
109125
GamepadHand mHand;
@@ -117,6 +133,9 @@ class Gamepad final : public nsISupports, public nsWrapperCache {
117133
DOMHighResTimeStamp mTimestamp;
118134
RefPtr<GamepadPose> mPose;
119135
nsTArray<RefPtr<GamepadHapticActuator>> mHapticActuators;
136+
nsTArray<RefPtr<GamepadLightIndicator>> mLightIndicators;
137+
nsTArray<RefPtr<GamepadTouch>> mTouchEvents;
138+
nsDataHashtable<nsUint32HashKey, uint32_t> mTouchIdHash;
120139
};
121140

122141
} // namespace dom

dom/gamepad/GamepadLightIndicator.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3+
/* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
5+
* You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+
#include "mozilla/dom/GamepadLightIndicator.h"
8+
#include "mozilla/dom/GamepadManager.h"
9+
#include "mozilla/dom/Promise.h"
10+
11+
namespace mozilla {
12+
namespace dom {
13+
14+
NS_IMPL_CYCLE_COLLECTING_ADDREF(GamepadLightIndicator)
15+
NS_IMPL_CYCLE_COLLECTING_RELEASE(GamepadLightIndicator)
16+
17+
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GamepadLightIndicator)
18+
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
19+
NS_INTERFACE_MAP_ENTRY(nsISupports)
20+
NS_INTERFACE_MAP_END
21+
22+
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GamepadLightIndicator, mParent)
23+
24+
GamepadLightIndicator::GamepadLightIndicator(nsISupports* aParent,
25+
uint32_t aGamepadId,
26+
uint32_t aIndex)
27+
: mParent(aParent),
28+
mType(DefaultType()),
29+
mGamepadId(aGamepadId),
30+
mIndex(aIndex) {}
31+
32+
GamepadLightIndicator::~GamepadLightIndicator() {
33+
mozilla::DropJSObjects(this);
34+
}
35+
36+
/* virtual */ JSObject* GamepadLightIndicator::WrapObject(
37+
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
38+
return GamepadLightIndicator_Binding::Wrap(aCx, this, aGivenProto);
39+
}
40+
41+
nsISupports* GamepadLightIndicator::GetParentObject() const { return mParent; }
42+
43+
already_AddRefed<Promise> GamepadLightIndicator::SetColor(
44+
const GamepadLightColor& color, ErrorResult& aRv) {
45+
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
46+
MOZ_ASSERT(global);
47+
48+
RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
49+
MOZ_ASSERT(gamepadManager);
50+
51+
RefPtr<Promise> promise = gamepadManager->SetLightIndicatorColor(
52+
mGamepadId, mIndex, color.mRed, color.mGreen, color.mBlue, global, aRv);
53+
if (!promise) {
54+
return nullptr;
55+
}
56+
return promise.forget();
57+
}
58+
59+
GamepadLightIndicatorType GamepadLightIndicator::Type() const { return mType; }
60+
61+
void GamepadLightIndicator::Set(const GamepadLightIndicator* aOther) {
62+
MOZ_ASSERT(aOther);
63+
mGamepadId = aOther->mGamepadId;
64+
mType = aOther->mType;
65+
mIndex = aOther->mIndex;
66+
}
67+
68+
} // namespace dom
69+
} // namespace mozilla

dom/gamepad/GamepadLightIndicator.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3+
/* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
5+
* You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+
#ifndef mozilla_dom_gamepad_GamepadLightIndicator_h
8+
#define mozilla_dom_gamepad_GamepadLightIndicator_h
9+
10+
#include "mozilla/dom/GamepadLightIndicatorBinding.h"
11+
12+
namespace mozilla {
13+
namespace dom {
14+
15+
class GamepadLightIndicator final : public nsISupports, public nsWrapperCache {
16+
public:
17+
GamepadLightIndicator(nsISupports* aParent, uint32_t aGamepadId,
18+
uint32_t aIndex);
19+
20+
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
21+
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GamepadLightIndicator)
22+
23+
static GamepadLightIndicatorType DefaultType() {
24+
return GamepadLightIndicatorType::Rgb;
25+
}
26+
27+
nsISupports* GetParentObject() const;
28+
29+
virtual JSObject* WrapObject(JSContext* aCx,
30+
JS::Handle<JSObject*> aGivenProto) override;
31+
32+
already_AddRefed<Promise> SetColor(const GamepadLightColor& color,
33+
ErrorResult& aRv);
34+
35+
void SetType(GamepadLightIndicatorType aType) { mType = aType; }
36+
37+
GamepadLightIndicatorType Type() const;
38+
39+
void Set(const GamepadLightIndicator* aOther);
40+
41+
private:
42+
virtual ~GamepadLightIndicator();
43+
44+
nsCOMPtr<nsISupports> mParent;
45+
GamepadLightIndicatorType mType;
46+
uint32_t mGamepadId;
47+
uint32_t mIndex;
48+
};
49+
50+
} // namespace dom
51+
} // namespace mozilla
52+
53+
#endif // mozilla_dom_gamepad_GamepadLightIndicator_h

dom/gamepad/GamepadTouch.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3+
/* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
5+
* You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+
#include "mozilla/dom/GamepadTouch.h"
8+
#include "mozilla/dom/GamepadManager.h"
9+
#include "mozilla/dom/Promise.h"
10+
11+
namespace mozilla {
12+
namespace dom {
13+
14+
NS_IMPL_CYCLE_COLLECTION_CLASS(GamepadTouch)
15+
16+
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(GamepadTouch)
17+
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
18+
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
19+
tmp->mPosition = nullptr;
20+
tmp->mSurfaceDimensions = nullptr;
21+
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
22+
23+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(GamepadTouch)
24+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
25+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
26+
27+
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(GamepadTouch)
28+
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
29+
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPosition)
30+
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSurfaceDimensions)
31+
NS_IMPL_CYCLE_COLLECTION_TRACE_END
32+
33+
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(GamepadTouch, AddRef)
34+
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(GamepadTouch, Release)
35+
36+
GamepadTouch::GamepadTouch(nsISupports* aParent)
37+
: mParent(aParent), mPosition(nullptr), mSurfaceDimensions(nullptr) {
38+
mozilla::HoldJSObjects(this);
39+
mTouchState = GamepadTouchState();
40+
}
41+
42+
GamepadTouch::~GamepadTouch() { mozilla::DropJSObjects(this); }
43+
44+
/* virtual */ JSObject* GamepadTouch::WrapObject(
45+
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
46+
return GamepadTouch_Binding::Wrap(aCx, this, aGivenProto);
47+
}
48+
49+
void GamepadTouch::GetPosition(JSContext* aCx,
50+
JS::MutableHandle<JSObject*> aRetval,
51+
ErrorResult& aRv) {
52+
mPosition = Float32Array::Create(aCx, this, 2, mTouchState.position);
53+
if (!mPosition) {
54+
aRv.NoteJSContextException(aCx);
55+
return;
56+
}
57+
58+
aRetval.set(mPosition);
59+
}
60+
61+
void GamepadTouch::GetSurfaceDimensions(JSContext* aCx,
62+
JS::MutableHandle<JSObject*> aRetval,
63+
ErrorResult& aRv) {
64+
mSurfaceDimensions = Uint32Array::Create(aCx, this, 2,
65+
mTouchState.isSurfaceDimensionsValid
66+
? mTouchState.surfaceDimensions
67+
: nullptr);
68+
69+
if (!mSurfaceDimensions) {
70+
aRv.NoteJSContextException(aCx);
71+
return;
72+
}
73+
74+
aRetval.set(mSurfaceDimensions);
75+
}
76+
77+
void GamepadTouch::SetTouchState(const GamepadTouchState& aTouch) {
78+
mTouchState = aTouch;
79+
}
80+
81+
void GamepadTouch::Set(const GamepadTouch* aOther) {
82+
MOZ_ASSERT(aOther);
83+
mTouchState = aOther->mTouchState;
84+
}
85+
86+
} // namespace dom
87+
} // namespace mozilla

0 commit comments

Comments
 (0)