michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "Gamepad.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsTArray.h" michael@0: #include "nsVariant.h" michael@0: #include "mozilla/dom/GamepadBinding.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: NS_IMPL_CYCLE_COLLECTING_ADDREF(Gamepad) michael@0: NS_IMPL_CYCLE_COLLECTING_RELEASE(Gamepad) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Gamepad) michael@0: NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(Gamepad, mParent, mButtons) michael@0: michael@0: Gamepad::Gamepad(nsISupports* aParent, michael@0: const nsAString& aID, uint32_t aIndex, michael@0: GamepadMappingType aMapping, michael@0: uint32_t aNumButtons, uint32_t aNumAxes) michael@0: : mParent(aParent), michael@0: mID(aID), michael@0: mIndex(aIndex), michael@0: mMapping(aMapping), michael@0: mConnected(true), michael@0: mButtons(aNumButtons), michael@0: mAxes(aNumAxes) michael@0: { michael@0: SetIsDOMBinding(); michael@0: for (unsigned i = 0; i < aNumButtons; i++) { michael@0: mButtons.InsertElementAt(i, new GamepadButton(mParent)); michael@0: } michael@0: mAxes.InsertElementsAt(0, aNumAxes, 0.0f); michael@0: } michael@0: michael@0: void michael@0: Gamepad::SetIndex(uint32_t aIndex) michael@0: { michael@0: mIndex = aIndex; michael@0: } michael@0: michael@0: void michael@0: Gamepad::SetConnected(bool aConnected) michael@0: { michael@0: mConnected = aConnected; michael@0: } michael@0: michael@0: void michael@0: Gamepad::SetButton(uint32_t aButton, bool aPressed, double aValue) michael@0: { michael@0: MOZ_ASSERT(aButton < mButtons.Length()); michael@0: mButtons[aButton]->SetPressed(aPressed); michael@0: mButtons[aButton]->SetValue(aValue); michael@0: } michael@0: michael@0: void michael@0: Gamepad::SetAxis(uint32_t aAxis, double aValue) michael@0: { michael@0: MOZ_ASSERT(aAxis < mAxes.Length()); michael@0: if (mAxes[aAxis] != aValue) { michael@0: mAxes[aAxis] = aValue; michael@0: GamepadBinding::ClearCachedAxesValue(this); michael@0: } michael@0: } michael@0: michael@0: void michael@0: Gamepad::SyncState(Gamepad* aOther) michael@0: { michael@0: if (mButtons.Length() != aOther->mButtons.Length() || michael@0: mAxes.Length() != aOther->mAxes.Length()) { michael@0: return; michael@0: } michael@0: michael@0: mConnected = aOther->mConnected; michael@0: for (uint32_t i = 0; i < mButtons.Length(); ++i) { michael@0: mButtons[i]->SetPressed(aOther->mButtons[i]->Pressed()); michael@0: mButtons[i]->SetValue(aOther->mButtons[i]->Value()); michael@0: } michael@0: bool changed = false; michael@0: for (uint32_t i = 0; i < mAxes.Length(); ++i) { michael@0: changed = changed || (mAxes[i] != aOther->mAxes[i]); michael@0: mAxes[i] = aOther->mAxes[i]; michael@0: } michael@0: if (changed) { michael@0: GamepadBinding::ClearCachedAxesValue(this); michael@0: } michael@0: } michael@0: michael@0: already_AddRefed michael@0: Gamepad::Clone(nsISupports* aParent) michael@0: { michael@0: nsRefPtr out = michael@0: new Gamepad(aParent, mID, mIndex, mMapping, michael@0: mButtons.Length(), mAxes.Length()); michael@0: out->SyncState(this); michael@0: return out.forget(); michael@0: } michael@0: michael@0: /* virtual */ JSObject* michael@0: Gamepad::WrapObject(JSContext* aCx) michael@0: { michael@0: return GamepadBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla