Add WTF::move()
[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::shared().registerNavigator(this);
47 }
48
49 NavigatorGamepad::~NavigatorGamepad()
50 {
51     GamepadManager::shared().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(), WTF::move(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 const Vector<RefPtr<Gamepad>>& NavigatorGamepad::getGamepads(Navigator* navigator)
76 {
77     return NavigatorGamepad::from(navigator)->gamepads();
78 }
79
80 const Vector<RefPtr<Gamepad>>& NavigatorGamepad::gamepads()
81 {
82     if (m_gamepads.isEmpty())
83         return m_gamepads;
84
85     const Vector<PlatformGamepad*>& platformGamepads = GamepadProvider::shared().platformGamepads();
86
87     for (unsigned i = 0; i < platformGamepads.size(); ++i) {
88         if (!platformGamepads[i]) {
89             ASSERT(!m_gamepads[i]);
90             continue;
91         }
92
93         ASSERT(m_gamepads[i]);
94         m_gamepads[i]->updateFromPlatformGamepad(*platformGamepads[i]);
95     }
96
97     return m_gamepads;
98 }
99
100 void NavigatorGamepad::gamepadsBecameVisible()
101 {
102     const Vector<PlatformGamepad*>& platformGamepads = GamepadProvider::shared().platformGamepads();
103     m_gamepads.resize(platformGamepads.size());
104
105     for (unsigned i = 0; i < platformGamepads.size(); ++i) {
106         if (!platformGamepads[i])
107             continue;
108
109         m_gamepads[i] = Gamepad::create(*platformGamepads[i], i);
110     }
111 }
112
113 void NavigatorGamepad::gamepadConnected(unsigned index)
114 {
115     // If this is the first gamepad this Navigator object has seen, then all gamepads just became visible.
116     if (m_gamepads.isEmpty()) {
117         gamepadsBecameVisible();
118         return;
119     }
120
121     // The new index should already fit in the existing array, or should be exactly one past-the-end of the existing array.
122     ASSERT(index <= m_gamepads.size());
123
124     const Vector<PlatformGamepad*>& platformGamepads = GamepadProvider::shared().platformGamepads();
125     ASSERT(index < platformGamepads.size());
126     ASSERT(platformGamepads[index]);
127
128     if (index < m_gamepads.size())
129         m_gamepads[index] = Gamepad::create(*platformGamepads[index], index);
130     else if (index == m_gamepads.size())
131         m_gamepads.append(Gamepad::create(*platformGamepads[index], index));
132 }
133
134 void NavigatorGamepad::gamepadDisconnected(unsigned index)
135 {
136     // If this Navigator hasn't seen any gamepads yet its Vector will still be empty.
137     if (!m_gamepads.size())
138         return;
139
140     ASSERT(index < m_gamepads.size());
141     ASSERT(m_gamepads[index]);
142
143     m_gamepads[index] = nullptr;
144 }
145
146 } // namespace WebCore
147
148 #endif // ENABLE(GAMEPAD)