Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / Modules / gamepad / NavigatorGamepad.cpp
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NavigatorGamepad.h"
28
29 #if ENABLE(GAMEPAD)
30
31 #include "DocumentLoader.h"
32 #include "Frame.h"
33 #include "Gamepad.h"
34 #include "GamepadManager.h"
35 #include "GamepadProvider.h"
36 #include "Navigator.h"
37 #include "PlatformGamepad.h"
38 #include <wtf/NeverDestroyed.h>
39 #include <wtf/RunLoop.h>
40
41 namespace WebCore {
42
43 NavigatorGamepad::NavigatorGamepad()
44     : m_navigationStart(std::numeric_limits<double>::infinity())
45 {
46     GamepadManager::singleton().registerNavigator(this);
47 }
48
49 NavigatorGamepad::~NavigatorGamepad()
50 {
51     GamepadManager::singleton().unregisterNavigator(this);
52 }
53
54 const char* NavigatorGamepad::supplementName()
55 {
56     return "NavigatorGamepad";
57 }
58
59 NavigatorGamepad* NavigatorGamepad::from(Navigator* navigator)
60 {
61     NavigatorGamepad* supplement = static_cast<NavigatorGamepad*>(Supplement<Navigator>::from(navigator, supplementName()));
62     if (!supplement) {
63         auto newSupplement = std::make_unique<NavigatorGamepad>();
64         supplement = newSupplement.get();
65         provideTo(navigator, supplementName(), WTFMove(newSupplement));
66
67         if (Frame* frame = navigator->frame()) {
68             if (DocumentLoader* documentLoader = frame->loader().documentLoader())
69                 supplement->m_navigationStart = documentLoader->timing().navigationStart();
70         }
71     }
72     return supplement;
73 }
74
75 Ref<Gamepad> NavigatorGamepad::gamepadFromPlatformGamepad(PlatformGamepad& platformGamepad)
76 {
77     unsigned index = platformGamepad.index();
78     if (index >= m_gamepads.size() || !m_gamepads[index])
79         return Gamepad::create(platformGamepad);
80
81     return *m_gamepads[index];
82 }
83
84 const Vector<RefPtr<Gamepad>>& NavigatorGamepad::getGamepads(Navigator& navigator)
85 {
86     return NavigatorGamepad::from(&navigator)->gamepads();
87 }
88
89 const Vector<RefPtr<Gamepad>>& NavigatorGamepad::gamepads()
90 {
91     if (m_gamepads.isEmpty())
92         return m_gamepads;
93
94     const Vector<PlatformGamepad*>& platformGamepads = GamepadProvider::singleton().platformGamepads();
95
96     for (unsigned i = 0; i < platformGamepads.size(); ++i) {
97         if (!platformGamepads[i]) {
98             ASSERT(!m_gamepads[i]);
99             continue;
100         }
101
102         ASSERT(m_gamepads[i]);
103         m_gamepads[i]->updateFromPlatformGamepad(*platformGamepads[i]);
104     }
105
106     return m_gamepads;
107 }
108
109 void NavigatorGamepad::gamepadsBecameVisible()
110 {
111     const Vector<PlatformGamepad*>& platformGamepads = GamepadProvider::singleton().platformGamepads();
112     m_gamepads.resize(platformGamepads.size());
113
114     for (unsigned i = 0; i < platformGamepads.size(); ++i) {
115         if (!platformGamepads[i])
116             continue;
117
118         m_gamepads[i] = Gamepad::create(*platformGamepads[i]);
119     }
120 }
121
122 void NavigatorGamepad::gamepadConnected(PlatformGamepad& platformGamepad)
123 {
124     // If this is the first gamepad this Navigator object has seen, then all gamepads just became visible.
125     if (m_gamepads.isEmpty()) {
126         gamepadsBecameVisible();
127         return;
128     }
129
130     unsigned index = platformGamepad.index();
131     ASSERT(GamepadProvider::singleton().platformGamepads()[index] == &platformGamepad);
132
133     // The new index should already fit in the existing array, or should be exactly one past-the-end of the existing array.
134     ASSERT(index <= m_gamepads.size());
135
136     if (index < m_gamepads.size())
137         m_gamepads[index] = Gamepad::create(platformGamepad);
138     else if (index == m_gamepads.size())
139         m_gamepads.append(Gamepad::create(platformGamepad));
140 }
141
142 void NavigatorGamepad::gamepadDisconnected(PlatformGamepad& platformGamepad)
143 {
144     // If this Navigator hasn't seen any gamepads yet its Vector will still be empty.
145     if (!m_gamepads.size())
146         return;
147
148     ASSERT(platformGamepad.index() < m_gamepads.size());
149     ASSERT(m_gamepads[platformGamepad.index()]);
150
151     m_gamepads[platformGamepad.index()] = nullptr;
152 }
153
154 } // namespace WebCore
155
156 #endif // ENABLE(GAMEPAD)