Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/gamepad/Gamepad.cpp
Line
Count
Source (jump to first uncovered line)
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 "Gamepad.h"
8
#include "nsPIDOMWindow.h"
9
#include "nsTArray.h"
10
#include "nsVariant.h"
11
#include "mozilla/dom/GamepadBinding.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
NS_IMPL_CYCLE_COLLECTING_ADDREF(Gamepad)
17
NS_IMPL_CYCLE_COLLECTING_RELEASE(Gamepad)
18
19
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Gamepad)
20
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
21
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
22
0
NS_INTERFACE_MAP_END
23
24
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Gamepad, mParent, mButtons, mPose,
25
                                      mHapticActuators)
26
27
void
28
Gamepad::UpdateTimestamp()
29
0
{
30
0
  nsCOMPtr<nsPIDOMWindowInner> newWindow(do_QueryInterface(mParent));
31
0
  if(newWindow) {
32
0
    Performance* perf = newWindow->GetPerformance();
33
0
    if (perf) {
34
0
      mTimestamp = perf->Now();
35
0
    }
36
0
  }
37
0
}
38
39
Gamepad::Gamepad(nsISupports* aParent,
40
                 const nsAString& aID, uint32_t aIndex,
41
                 uint32_t aHashKey,
42
                 GamepadMappingType aMapping,
43
                 GamepadHand aHand,
44
                 uint32_t aDisplayID, uint32_t aNumButtons,
45
                 uint32_t aNumAxes, uint32_t aNumHaptics)
46
  : mParent(aParent),
47
    mID(aID),
48
    mIndex(aIndex),
49
    mHashKey(aHashKey),
50
    mDisplayId(aDisplayID),
51
    mMapping(aMapping),
52
    mHand(aHand),
53
    mConnected(true),
54
    mButtons(aNumButtons),
55
    mAxes(aNumAxes),
56
    mTimestamp(0)
57
0
{
58
0
  for (unsigned i = 0; i < aNumButtons; i++) {
59
0
    mButtons.InsertElementAt(i, new GamepadButton(mParent));
60
0
  }
61
0
  mAxes.InsertElementsAt(0, aNumAxes, 0.0f);
62
0
  mPose = new GamepadPose(aParent);
63
0
  for (uint32_t i = 0; i < aNumHaptics; ++i) {
64
0
    mHapticActuators.AppendElement(new GamepadHapticActuator(mParent, mHashKey, i));
65
0
  }
66
0
  UpdateTimestamp();
67
0
}
68
69
void
70
Gamepad::SetIndex(uint32_t aIndex)
71
0
{
72
0
  mIndex = aIndex;
73
0
}
74
75
void
76
Gamepad::SetConnected(bool aConnected)
77
0
{
78
0
  mConnected = aConnected;
79
0
}
80
81
void
82
Gamepad::SetButton(uint32_t aButton, bool aPressed,
83
                   bool aTouched, double aValue)
84
0
{
85
0
  MOZ_ASSERT(aButton < mButtons.Length());
86
0
  mButtons[aButton]->SetPressed(aPressed);
87
0
  mButtons[aButton]->SetTouched(aTouched);
88
0
  mButtons[aButton]->SetValue(aValue);
89
0
  UpdateTimestamp();
90
0
}
91
92
void
93
Gamepad::SetAxis(uint32_t aAxis, double aValue)
94
0
{
95
0
  MOZ_ASSERT(aAxis < mAxes.Length());
96
0
  if (mAxes[aAxis] != aValue) {
97
0
    mAxes[aAxis] = aValue;
98
0
    Gamepad_Binding::ClearCachedAxesValue(this);
99
0
  }
100
0
  UpdateTimestamp();
101
0
}
102
103
void
104
Gamepad::SetPose(const GamepadPoseState& aPose)
105
0
{
106
0
  mPose->SetPoseState(aPose);
107
0
  UpdateTimestamp();
108
0
}
109
110
void
111
Gamepad::SetHand(GamepadHand aHand)
112
0
{
113
0
  mHand = aHand;
114
0
}
115
116
void
117
Gamepad::SyncState(Gamepad* aOther)
118
0
{
119
0
  const char* kGamepadExtEnabledPref = "dom.gamepad.extensions.enabled";
120
0
121
0
  if (mButtons.Length() != aOther->mButtons.Length() ||
122
0
      mAxes.Length() != aOther->mAxes.Length()) {
123
0
    return;
124
0
  }
125
0
126
0
  mConnected = aOther->mConnected;
127
0
  for (uint32_t i = 0; i < mButtons.Length(); ++i) {
128
0
    mButtons[i]->SetPressed(aOther->mButtons[i]->Pressed());
129
0
    mButtons[i]->SetTouched(aOther->mButtons[i]->Touched());
130
0
    mButtons[i]->SetValue(aOther->mButtons[i]->Value());
131
0
  }
132
0
133
0
  bool changed = false;
134
0
  for (uint32_t i = 0; i < mAxes.Length(); ++i) {
135
0
    changed = changed || (mAxes[i] != aOther->mAxes[i]);
136
0
    mAxes[i] = aOther->mAxes[i];
137
0
  }
138
0
  if (changed) {
139
0
    Gamepad_Binding::ClearCachedAxesValue(this);
140
0
  }
141
0
142
0
  if (Preferences::GetBool(kGamepadExtEnabledPref)) {
143
0
    MOZ_ASSERT(aOther->GetPose());
144
0
    mPose->SetPoseState(aOther->GetPose()->GetPoseState());
145
0
    mHand = aOther->Hand();
146
0
    for (uint32_t i = 0; i < mHapticActuators.Length(); ++i) {
147
0
      mHapticActuators[i]->Set(aOther->mHapticActuators[i]);
148
0
    }
149
0
  }
150
0
151
0
  UpdateTimestamp();
152
0
}
153
154
already_AddRefed<Gamepad>
155
Gamepad::Clone(nsISupports* aParent)
156
0
{
157
0
  RefPtr<Gamepad> out =
158
0
    new Gamepad(aParent, mID, mIndex, mHashKey, mMapping,
159
0
                mHand, mDisplayId, mButtons.Length(), mAxes.Length(),
160
0
                mHapticActuators.Length());
161
0
  out->SyncState(this);
162
0
  return out.forget();
163
0
}
164
165
/* virtual */ JSObject*
166
Gamepad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
167
0
{
168
0
  return Gamepad_Binding::Wrap(aCx, this, aGivenProto);
169
0
}
170
171
} // namespace dom
172
} // namespace mozilla