tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XRInputSourceArray.cpp (5534B)


      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/XRInputSourceArray.h"
      8 
      9 #include "VRDisplayClient.h"
     10 #include "mozilla/dom/XRInputSourcesChangeEvent.h"
     11 #include "mozilla/dom/XRSession.h"
     12 
     13 namespace mozilla::dom {
     14 
     15 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(XRInputSourceArray, mParent,
     16                                      mInputSources)
     17 NS_IMPL_CYCLE_COLLECTING_ADDREF(XRInputSourceArray)
     18 NS_IMPL_CYCLE_COLLECTING_RELEASE(XRInputSourceArray)
     19 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XRInputSourceArray)
     20  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     21  NS_INTERFACE_MAP_ENTRY(nsISupports)
     22 NS_INTERFACE_MAP_END
     23 
     24 XRInputSourceArray::XRInputSourceArray(nsISupports* aParent)
     25    : mParent(aParent) {}
     26 
     27 JSObject* XRInputSourceArray::WrapObject(JSContext* aCx,
     28                                         JS::Handle<JSObject*> aGivenProto) {
     29  return XRInputSourceArray_Binding::Wrap(aCx, this, aGivenProto);
     30 }
     31 
     32 void XRInputSourceArray::Update(XRSession* aSession) {
     33  MOZ_ASSERT(aSession);
     34 
     35  gfx::VRDisplayClient* displayClient = aSession->GetDisplayClient();
     36  if (!displayClient) {
     37    return;
     38  }
     39 
     40  XRInputSourcesChangeEventInit addInit;
     41  nsTArray<RefPtr<XRInputSource>> removedInputs;
     42  if (NS_WARN_IF(!addInit.mAdded.SetCapacity(gfx::kVRControllerMaxCount,
     43                                             mozilla::fallible))) {
     44    MOZ_ASSERT(false,
     45               "'add' sequence in XRInputSourcesChangeEventInit SetCapacity() "
     46               "failed.");
     47    return;
     48  }
     49 
     50  for (int32_t i = 0; i < gfx::kVRControllerMaxCount; ++i) {
     51    const gfx::VRControllerState& controllerState =
     52        displayClient->GetDisplayInfo().mControllerState[i];
     53    if (controllerState.controllerName[0] == '\0') {
     54      // Checking if exising controllers need to be removed.
     55      for (auto& input : mInputSources) {
     56        if (input->GetIndex() == i) {
     57          removedInputs.AppendElement(input);
     58          break;
     59        }
     60      }
     61      continue;
     62    }
     63 
     64    bool found = false;
     65    RefPtr<XRInputSource> inputSource = nullptr;
     66    for (auto& input : mInputSources) {
     67      if (input->GetIndex() == i) {
     68        found = true;
     69        inputSource = input;
     70        break;
     71      }
     72    }
     73    // Checking if it is added before.
     74    if (!found &&
     75        (controllerState.numButtons > 0 || controllerState.numAxes > 0)) {
     76      inputSource = new XRInputSource(mParent);
     77      inputSource->Setup(aSession, i);
     78      mInputSources.AppendElement(inputSource);
     79 
     80      addInit.mBubbles = false;
     81      addInit.mCancelable = false;
     82      addInit.mSession = aSession;
     83      if (!addInit.mAdded.AppendElement(*inputSource, mozilla::fallible)) {
     84        MOZ_ASSERT(false,
     85                   "'add' sequence in XRInputSourcesChangeEventInit "
     86                   "AppendElement() failed, it might be due to the"
     87                   "wrong size when SetCapacity().");
     88      }
     89    }
     90    // If added, updating the current controller states.
     91    if (inputSource) {
     92      inputSource->Update(aSession);
     93    }
     94  }
     95 
     96  // Send `inputsourceschange` for new controllers.
     97  if (addInit.mAdded.Length()) {
     98    RefPtr<XRInputSourcesChangeEvent> event =
     99        XRInputSourcesChangeEvent::Constructor(
    100            aSession, u"inputsourceschange"_ns, addInit);
    101 
    102    event->SetTrusted(true);
    103    aSession->DispatchEvent(*event);
    104  }
    105 
    106  // If there's a controller is removed, dispatch `inputsourceschange`.
    107  if (removedInputs.Length()) {
    108    DispatchInputSourceRemovedEvent(removedInputs, aSession);
    109  }
    110  for (auto& input : removedInputs) {
    111    mInputSources.RemoveElement(input);
    112  }
    113 }
    114 
    115 void XRInputSourceArray::DispatchInputSourceRemovedEvent(
    116    const nsTArray<RefPtr<XRInputSource>>& aInputs, XRSession* aSession) {
    117  if (!aSession) {
    118    return;
    119  }
    120 
    121  XRInputSourcesChangeEventInit init;
    122  if (NS_WARN_IF(
    123          !init.mRemoved.SetCapacity(aInputs.Length(), mozilla::fallible))) {
    124    MOZ_ASSERT(false,
    125               "'removed' sequence in XRInputSourcesChangeEventInit "
    126               "SetCapacity() failed.");
    127    return;
    128  }
    129  for (const auto& input : aInputs) {
    130    input->SetGamepadIsConnected(false, aSession);
    131    init.mBubbles = false;
    132    init.mCancelable = false;
    133    init.mSession = aSession;
    134    if (!init.mRemoved.AppendElement(*input, mozilla::fallible)) {
    135      MOZ_ASSERT(false,
    136                 "'removed' sequence in XRInputSourcesChangeEventInit "
    137                 "AppendElement() failed, it might be due to the"
    138                 "wrong size when SetCapacity().");
    139    }
    140  }
    141 
    142  if (init.mRemoved.Length()) {
    143    RefPtr<XRInputSourcesChangeEvent> event =
    144        XRInputSourcesChangeEvent::Constructor(aSession,
    145                                               u"inputsourceschange"_ns, init);
    146 
    147    event->SetTrusted(true);
    148    aSession->DispatchEvent(*event);
    149  }
    150 }
    151 
    152 void XRInputSourceArray::Clear(XRSession* aSession) {
    153  DispatchInputSourceRemovedEvent(mInputSources, aSession);
    154  mInputSources.Clear();
    155 }
    156 
    157 uint32_t XRInputSourceArray::Length() { return mInputSources.Length(); }
    158 
    159 XRInputSource* XRInputSourceArray::IndexedGetter(uint32_t aIndex,
    160                                                 bool& aFound) {
    161  aFound = aIndex < mInputSources.Length();
    162  if (!aFound) {
    163    return nullptr;
    164  }
    165  return mInputSources[aIndex];
    166 }
    167 
    168 }  // namespace mozilla::dom