Skip to content

Commit 9e2d610

Browse files
committed
Partial refactor of VirtualController.
1 parent 52b4510 commit 9e2d610

File tree

13 files changed

+274
-155
lines changed

13 files changed

+274
-155
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,9 @@ file(GLOB MAIN_SOURCES
609609
Source/Controllers/ControllerSession.h
610610
Source/Controllers/ControllerSelectorWidget.cpp
611611
Source/Controllers/ControllerSelectorWidget.h
612+
Source/Controllers/GlobalQtKeyMap.cpp
613+
Source/Controllers/GlobalQtKeyMap.h
614+
Source/Controllers/KeyboardStateTracker.h
612615
Source/Controllers/NullController.cpp
613616
Source/Controllers/NullController.h
614617
Source/Controllers/SuperscalarScheduler.cpp

SerialPrograms/SerialPrograms.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ SOURCES += \
310310
Source/Controllers/ControllerSelectorWidget.cpp \
311311
Source/Controllers/ControllerSession.cpp \
312312
Source/Controllers/ControllerDescriptor.cpp \
313+
Source/Controllers/GlobalQtKeyMap.cpp \
313314
Source/Controllers/NullController.cpp \
314315
Source/Controllers/SerialPABotBase/SerialPABotBase.cpp \
315316
Source/Controllers/SerialPABotBase/SerialPABotBase_Handle.cpp \
@@ -1426,6 +1427,8 @@ HEADERS += \
14261427
Source/Controllers/ControllerSelectorWidget.h \
14271428
Source/Controllers/ControllerSession.h \
14281429
Source/Controllers/ControllerDescriptor.h \
1430+
Source/Controllers/GlobalQtKeyMap.h \
1431+
Source/Controllers/KeyboardStateTracker.h \
14291432
Source/Controllers/NullController.h \
14301433
Source/Controllers/SerialPABotBase/SerialPABotBase.h \
14311434
Source/Controllers/SerialPABotBase/SerialPABotBase_Handle.h \

SerialPrograms/Source/CommonTools/InferenceCallbacks/VisualInferenceCallback.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
#ifndef PokemonAutomation_CommonTools_VisualInferenceCallback_H
88
#define PokemonAutomation_CommonTools_VisualInferenceCallback_H
99

10-
#include <memory>
1110
#include <string>
12-
#include "Common/Compiler.h"
1311
#include "Common/Cpp/Time.h"
1412
#include "InferenceCallback.h"
1513

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* Global Qt Key Map
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#include <QKeyEvent>
8+
#include "Common/Cpp/Exceptions.h"
9+
#include "Common/Cpp/Concurrency/SpinLock.h"
10+
#include "GlobalQtKeyMap.h"
11+
12+
namespace PokemonAutomation{
13+
14+
15+
16+
void QtKeyMap::record(const QKeyEvent& event){
17+
uint32_t native_key = event.nativeVirtualKey();
18+
if (native_key == 0){
19+
return;
20+
}
21+
Qt::Key qkey = (Qt::Key)event.key();
22+
WriteSpinLock lg(m_lock);
23+
m_map[native_key].insert(qkey);
24+
}
25+
26+
const std::set<Qt::Key>& QtKeyMap::get_QtKeys(uint32_t native_key) const{
27+
ReadSpinLock lg(m_lock);
28+
auto iter = m_map.find(native_key);
29+
if (iter == m_map.end()){
30+
throw InternalProgramError(
31+
nullptr, PA_CURRENT_FUNCTION,
32+
"Attempted to look up unrecognized native keyboard key: " + std::to_string(native_key)
33+
);
34+
}
35+
return iter->second;
36+
}
37+
38+
39+
40+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* Global Qt Key Map
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_Controllers_GlobalQtKeyMap_H
8+
#define PokemonAutomation_Controllers_GlobalQtKeyMap_H
9+
10+
#include <set>
11+
#include <map>
12+
#include <QKeyEvent>
13+
#include "Common/Cpp/Concurrency/SpinLock.h"
14+
15+
namespace PokemonAutomation{
16+
17+
18+
19+
20+
class QtKeyMap{
21+
public:
22+
static QtKeyMap& instance(){
23+
static QtKeyMap map;
24+
return map;
25+
}
26+
27+
void record(const QKeyEvent& event);
28+
29+
const std::set<Qt::Key>& get_QtKeys(uint32_t native_key) const;
30+
31+
32+
private:
33+
QtKeyMap() = default;
34+
35+
36+
private:
37+
mutable SpinLock m_lock;
38+
// Map of native key to Qt's key ID.
39+
std::map<uint32_t, std::set<Qt::Key>> m_map;
40+
};
41+
42+
43+
44+
}
45+
#endif
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/* Keyboard State Tracker
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_Controllers_KeyboardStateTracker_H
8+
#define PokemonAutomation_Controllers_KeyboardStateTracker_H
9+
10+
#include <deque>
11+
#include <set>
12+
#include "Common/Cpp/Time.h"
13+
14+
namespace PokemonAutomation{
15+
16+
17+
18+
class KeyboardStateTracker{
19+
public:
20+
KeyboardStateTracker(std::chrono::milliseconds debounce_period = std::chrono::milliseconds(10))
21+
: m_debounce_period(debounce_period)
22+
{}
23+
24+
25+
public:
26+
void clear(){
27+
m_committed.clear();
28+
m_pending.clear();
29+
}
30+
void press(uint32_t key){
31+
WallClock now = current_time();
32+
m_pending.emplace_back(Event{now, true, key});
33+
move_old_events(now);
34+
}
35+
void release(uint32_t key){
36+
WallClock now = current_time();
37+
m_pending.emplace_back(Event{now, false, key});
38+
move_old_events(now);
39+
}
40+
41+
42+
public:
43+
WallClock next_state_change() const{
44+
return m_pending.empty()
45+
? WallClock::max()
46+
: m_pending.begin()->timestamp + m_debounce_period;
47+
}
48+
std::set<uint32_t> get_currently_pressed(){
49+
WallClock now = current_time();
50+
move_old_events(now);
51+
52+
// Copy the current committed set.
53+
std::set<uint32_t> ret = m_committed;
54+
55+
// Now process all the pending ones - ignoring the release events.
56+
for (const Event& event : m_pending){
57+
if (event.press){
58+
ret.insert(event.key);
59+
}
60+
}
61+
62+
return ret;
63+
}
64+
65+
66+
private:
67+
// Move all pending events that are old enough to the committed set.
68+
void move_old_events(WallClock now){
69+
WallClock threshold = now - m_debounce_period;
70+
while (!m_pending.empty()){
71+
Event& event = m_pending.front();
72+
73+
// Always commit presses.
74+
if (event.press){
75+
m_committed.insert(event.key);
76+
m_pending.pop_front();
77+
continue;
78+
}
79+
80+
// Release is old enough. Commit it.
81+
if (event.timestamp < threshold){
82+
m_committed.erase(event.key);
83+
m_pending.pop_front();
84+
continue;
85+
}
86+
87+
// We've hit an uncommittable release. We're done.
88+
break;
89+
}
90+
}
91+
92+
93+
private:
94+
struct Event{
95+
WallClock timestamp;
96+
bool press;
97+
uint32_t key;
98+
};
99+
std::chrono::milliseconds m_debounce_period;
100+
std::set<uint32_t> m_committed;
101+
std::deque<Event> m_pending;
102+
};
103+
104+
105+
106+
}
107+
#endif

SerialPrograms/Source/Controllers/NullController.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*
55
*/
66

7-
#ifndef PokemonAutomation_Controllers_Null_H
8-
#define PokemonAutomation_Controllers_Null_H
7+
#ifndef PokemonAutomation_Controllers_NullController_H
8+
#define PokemonAutomation_Controllers_NullController_H
99

1010
#include "ControllerDescriptor.h"
1111

0 commit comments

Comments
 (0)