Skip to content

Commit abf0ca3

Browse files
committed
Merge branch 'thumbbehavior'
2 parents 89545f0 + 9e938b8 commit abf0ca3

33 files changed

+609
-514
lines changed

XMapLib/CPPRunnerGeneric.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ namespace sds
3232
const LambdaType m_lambda;
3333
InternalData m_local_state{}; // default constructed type InternalData
3434
std::atomic<bool> m_is_stop_requested{ false };
35-
std::unique_ptr<std::thread> m_local_thread;
36-
std::mutex m_state_mutex;
35+
std::unique_ptr<std::thread> m_local_thread{};
36+
std::mutex m_state_mutex{};
3737
public:
3838
/// <summary>Starts running a new thread for the lambda.</summary>
3939
/// <returns>true on success, false on failure.</returns>

XMapLib/DelayManager.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ namespace sds::Utilities
77
class DelayManager
88
{
99
using TimeType = std::chrono::time_point<std::chrono::high_resolution_clock>;
10-
TimeType m_start_time = std::chrono::high_resolution_clock::now();
11-
size_t m_duration = 1;
12-
bool m_has_fired = false;
10+
TimeType m_start_time{ std::chrono::high_resolution_clock::now() };
11+
size_t m_duration{ 1 };
12+
bool m_has_fired{ false };
1313
public:
1414
//us is microseconds
1515
DelayManager() = delete;
16-
DelayManager(size_t duration_us) : m_duration(duration_us) { }
16+
explicit DelayManager(size_t duration_us) : m_duration(duration_us) { }
1717
DelayManager(const DelayManager& other) = default;
1818
DelayManager(DelayManager&& other) = default;
1919
DelayManager& operator=(const DelayManager& other) = default;

XMapLib/KeyboardInputPoller.h

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ namespace sds
1313
using InternalType = std::vector<XINPUT_KEYSTROKE>;
1414
using LambdaRunnerType = sds::CPPRunnerGeneric<InternalType>;
1515
using lock = LambdaRunnerType::ScopedLockType;
16-
const int EMPTY_COUNT = 5000;
17-
KeyboardPlayerInfo m_local_player;
18-
std::unique_ptr<LambdaRunnerType> m_workThread;
16+
const int EMPTY_COUNT{ 5000 };
17+
KeyboardPlayerInfo m_local_player{};
18+
std::unique_ptr<LambdaRunnerType> m_workThread{};
1919
void InitWorkThread() noexcept
2020
{
2121
m_workThread =
@@ -33,58 +33,43 @@ namespace sds
3333
KeyboardInputPoller(KeyboardInputPoller&& other) = delete;
3434
KeyboardInputPoller& operator=(const KeyboardInputPoller& other) = delete;
3535
KeyboardInputPoller& operator=(KeyboardInputPoller&& other) = delete;
36-
/// <summary>
37-
/// Destructor override, ensures the running thread function is stopped
38-
/// inside of this class and not the base.
39-
/// </summary>
40-
~KeyboardInputPoller()
41-
{
42-
Stop();
43-
}
36+
~KeyboardInputPoller() = default;
37+
38+
/// <summary>Returns copy and clears internal one.</summary>
4439
std::vector<XINPUT_KEYSTROKE> getAndClearStates() const
4540
{
4641
return m_workThread->GetAndClearCurrentStates();
4742
}
48-
/// <summary>
49-
/// Start polling for updated XINPUT_STATE info.
50-
/// </summary>
43+
/// <summary>Start polling for updated XINPUT_KEYSTROKE info.</summary>
5144
void Start() const noexcept
5245
{
5346
if (m_workThread)
5447
m_workThread->StartThread();
5548
}
56-
/// <summary>
57-
/// Stop input polling.
58-
/// </summary>
49+
/// <summary>Stop input polling.</summary>
5950
void Stop() const noexcept
6051
{
6152
if (m_workThread)
6253
m_workThread->StopThread();
6354
}
64-
/// <summary>
65-
/// Gets the running status of the worker thread
66-
/// </summary>
55+
/// <summary>Gets the running status of the worker thread</summary>
6756
/// <returns> true if thread is running, false otherwise</returns>
6857
bool IsRunning() const noexcept
6958
{
7059
if (m_workThread)
7160
return m_workThread->IsRunning();
7261
return false;
7362
}
74-
/// <summary>
75-
/// Returns status of XINPUT library detecting a controller.
76-
/// </summary>
63+
/// <summary>Returns status of XINPUT library detecting a controller.</summary>
7764
/// <returns> true if controller is connected, false otherwise</returns>
7865
bool IsControllerConnected() const noexcept
7966
{
8067
XINPUT_KEYSTROKE ss{};
8168
const DWORD ret = XInputGetKeystroke(m_local_player.player_id,0, &ss);
8269
return ret == ERROR_SUCCESS || ret == ERROR_EMPTY;
8370
}
84-
/// <summary>
85-
/// Returns status of XINPUT library detecting a controller.
86-
/// overload that uses the player_id value in a KeyboardPlayerInfo struct
87-
/// </summary>
71+
/// <summary>Returns status of XINPUT library detecting a controller.
72+
/// This overload uses the player_id value in a KeyboardPlayerInfo struct</summary>
8873
/// <returns> true if controller is connected, false otherwise</returns>
8974
bool IsControllerConnected(const KeyboardPlayerInfo& p) const noexcept
9075
{
@@ -93,10 +78,7 @@ namespace sds
9378
return ret == ERROR_SUCCESS || ret == ERROR_EMPTY;
9479
}
9580
protected:
96-
/// <summary>
97-
/// Worker thread overriding the base pure virtual workThread.
98-
/// Updates "m_local_state" with mutex protection.
99-
/// </summary>
81+
/// <summary>Worker thread used by m_workThread. Updates the protectedData with mutex protection.</summary>
10082
void workThread(sds::LambdaArgs::LambdaArg1& stopCondition, sds::LambdaArgs::LambdaArg2& mut, auto& protectedData)
10183
{
10284
auto addElement = [this,&mut,&protectedData](const XINPUT_KEYSTROKE& state)

XMapLib/KeyboardKeyMap.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ namespace sds
2121
KEYUP = XINPUT_KEYSTROKE_KEYUP
2222
};
2323
//Struct members
24-
int SendingElementVK = 0; // VK of controller button
25-
int MappedToVK = 0; // VK of mapped-to input (key or mouse button)
26-
bool UsesRepeat = true; // Uses the key-repeat behavior when held down
27-
ActionType LastAction = ActionType::NONE;
28-
Utilities::DelayManager LastSentTime = KeyboardSettings::MICROSECONDS_DELAY_KEYREPEAT;
24+
int SendingElementVK{ 0 }; // VK of controller button
25+
int MappedToVK{ 0 }; // VK of mapped-to input (key or mouse button)
26+
bool UsesRepeat{ true }; // Uses the key-repeat behavior when held down
27+
ActionType LastAction{ ActionType::NONE };
28+
Utilities::DelayManager LastSentTime{ KeyboardSettings::MICROSECONDS_DELAY_KEYREPEAT };
2929
//Ctor
3030
KeyboardKeyMap(const int controllerElementVK, const int keyboardMouseElementVK, const bool useRepeat)
3131
: SendingElementVK(controllerElementVK), MappedToVK(keyboardMouseElementVK), UsesRepeat(useRepeat)

XMapLib/KeyboardMapper.h

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,24 @@ namespace sds
1414
using InternalType = int;
1515
using LambdaRunnerType = sds::CPPRunnerGeneric<InternalType>;
1616
using lock = LambdaRunnerType::ScopedLockType;
17-
sds::KeyboardPlayerInfo m_localPlayerInfo;
18-
sds::KeyboardInputPoller m_poller;
19-
sds::KeyboardTranslator m_translator;
20-
std::unique_ptr<LambdaRunnerType> m_workThread;
17+
sds::KeyboardPlayerInfo m_localPlayerInfo{};
18+
sds::KeyboardInputPoller m_poller{};
19+
sds::KeyboardTranslator m_translator{};
20+
std::unique_ptr<LambdaRunnerType> m_workThread{};
2121
void InitWorkThread() noexcept
2222
{
2323
m_workThread =
2424
std::make_unique<LambdaRunnerType>
2525
([this](auto& stopCondition, auto& mut, auto& protectedData) { workThread(stopCondition, mut, protectedData); });
2626
}
2727
public:
28-
/// <summary>
29-
/// Ctor for default configuration
30-
/// </summary>
28+
/// <summary>Ctor for default configuration</summary>
3129
KeyboardMapper()
3230
{
3331
InitWorkThread();
3432
Start();
3533
}
36-
/// <summary>
37-
/// Ctor allows setting a custom KeyboardPlayerInfo
38-
/// </summary>
34+
/// <summary>Ctor allows setting a custom KeyboardPlayerInfo</summary>
3935
explicit KeyboardMapper(const sds::KeyboardPlayerInfo& player) : m_localPlayerInfo(player)
4036
{
4137
InitWorkThread();
@@ -45,14 +41,11 @@ namespace sds
4541
KeyboardMapper(KeyboardMapper&& other) = delete;
4642
KeyboardMapper& operator=(const KeyboardMapper& other) = delete;
4743
KeyboardMapper& operator=(KeyboardMapper&& other) = delete;
48-
/// <summary>
49-
/// Destructor override, ensures the running thread function is stopped
50-
/// inside of this class and not the base.
51-
/// </summary>
5244
~KeyboardMapper()
5345
{
5446
Stop();
5547
}
48+
5649
bool IsControllerConnected() const
5750
{
5851
return m_poller.IsControllerConnected();
@@ -66,8 +59,9 @@ namespace sds
6659
m_poller.Start();
6760
m_workThread->StartThread();
6861
}
69-
void Stop() const noexcept
62+
void Stop() noexcept
7063
{
64+
m_translator.CleanupInProgressEvents();
7165
m_poller.Stop();
7266
m_workThread->StopThread();
7367
}
@@ -86,13 +80,10 @@ namespace sds
8680
}
8781
void ClearMaps()
8882
{
89-
m_translator.ClearMap();
83+
m_translator.ClearMaps();
9084
}
9185
protected:
92-
/// <summary>
93-
/// Worker thread, protected visibility.
94-
/// Accesses the std::atomic m_threadX and m_threadY members.
95-
/// </summary>
86+
/// <summary>Worker thread, protected visibility.</summary>
9687
void workThread(auto& stopCondition, auto&, auto&)
9788
{
9889
//thread main loop

XMapLib/KeyboardSettings.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ namespace sds
77
struct KeyboardSettings
88
{
99
//Input Poller maximum number of XINPUT_KEYSTROKE structs to queue before dropping input.
10-
constexpr static const int MAX_STATE_COUNT = 128;
10+
constexpr static const int MAX_STATE_COUNT{ 128 };
1111
//Input Poller thread delay, in milliseconds.
12-
constexpr static const int THREAD_DELAY_POLLER = 10;
12+
constexpr static const int THREAD_DELAY_POLLER{ 10 };
1313
//Microseconds Delay Keyrepeat is the time delay a button has in between activations.
14-
constexpr static const int MICROSECONDS_DELAY_KEYREPEAT = 100000;
14+
constexpr static const int MICROSECONDS_DELAY_KEYREPEAT{ 100000 };
1515
//It is necessary to be able to distinguish these mapping values in KeyboardTranslator.
1616
constexpr static std::array<int,8> THUMBSTICK_L_VK_LIST
1717
{

XMapLib/KeyboardTranslator.h

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ namespace sds
1515
/// </summary>
1616
class KeyboardTranslator
1717
{
18-
const std::string ERR_BAD_VK = "Either WordData.MappedToVK OR WordData.SendElementVK is <= 0";
19-
const std::string ERR_DUP_KEYUP = "Sent a duplicate keyup event to handle thumbstick direction changing behavior.";
2018
using ClockType = std::chrono::high_resolution_clock;
2119
using PointInTime = std::chrono::time_point<ClockType>;
2220
using InpType = sds::KeyboardKeyMap::ActionType;
21+
const std::string ERR_BAD_VK{ "Either WordData.MappedToVK OR WordData.SendElementVK is <= 0" };
22+
const std::string ERR_DUP_KEYUP{ "Sent a duplicate keyup event to handle thumbstick direction changing behavior." };
2323
private:
24-
Utilities::SendKeyInput m_key_send;
25-
std::vector<KeyboardKeyMap> m_map_token_info;
26-
KeyboardPlayerInfo m_local_player;
24+
Utilities::SendKeyInput m_key_send{};
25+
std::vector<KeyboardKeyMap> m_map_token_info{};
26+
KeyboardPlayerInfo m_local_player{};
2727
public:
2828
explicit KeyboardTranslator(const KeyboardPlayerInfo &p) : m_local_player(p)
2929
{
@@ -50,6 +50,17 @@ namespace sds
5050
}
5151
}
5252
}
53+
/// <summary>Call this function to send key-ups for any in-progress key presses.</summary>
54+
void CleanupInProgressEvents()
55+
{
56+
for(auto &m: m_map_token_info)
57+
{
58+
if(m.LastAction == InpType::KEYDOWN || m.LastAction == InpType::KEYREPEAT)
59+
{
60+
this->DoOvertaking(m);
61+
}
62+
}
63+
}
5364
std::string AddKeyMap(KeyboardKeyMap w)
5465
{
5566
std::string result = CheckForVKError(w);
@@ -58,11 +69,11 @@ namespace sds
5869
m_map_token_info.push_back(w);
5970
return "";
6071
}
61-
void ClearMap()
72+
void ClearMaps() noexcept
6273
{
6374
m_map_token_info.clear();
6475
}
65-
std::vector<KeyboardKeyMap> GetMaps() const
76+
std::vector<KeyboardKeyMap> GetMaps() const noexcept
6677
{
6778
return m_map_token_info;
6879
}
@@ -91,9 +102,7 @@ namespace sds
91102
}
92103
}
93104
}
94-
/// <summary>
95-
/// Normal keypress simulation logic.
96-
/// </summary>
105+
/// <summary>Normal keypress simulation logic.</summary>
97106
void Normal(KeyboardKeyMap &detail, const XINPUT_KEYSTROKE &stroke)
98107
{
99108
const bool DoDown = (detail.LastAction == InpType::NONE) && (stroke.Flags & static_cast<WORD>(InpType::KEYDOWN));
@@ -111,17 +120,15 @@ namespace sds
111120
SendTheKey(detail, false, InpType::KEYUP);
112121
}
113122
}
114-
//Does the key send call, updates LastAction and updates LastSentTime
115-
void SendTheKey(KeyboardKeyMap& mp, const bool keyDown, KeyboardKeyMap::ActionType action)
123+
/// <summary>Does the key send call, updates LastAction and updates LastSentTime</summary>
124+
void SendTheKey(KeyboardKeyMap& mp, const bool keyDown, KeyboardKeyMap::ActionType action) noexcept
116125
{
117126
//std::cerr << mp << std::endl; // temp logging
118127
mp.LastAction = action;
119128
m_key_send.SendScanCode(mp.MappedToVK, keyDown);
120129
mp.LastSentTime.Reset(KeyboardSettings::MICROSECONDS_DELAY_KEYREPEAT); // update last sent time
121130
}
122-
/// <summary>
123-
/// Check to see if a different axis of the same thumbstick has been pressed already
124-
/// </summary>
131+
/// <summary>Check to see if a different axis of the same thumbstick has been pressed already</summary>
125132
/// <param name="detail">Newest element being set to keydown state</param>
126133
/// <param name="outOvertaken">out key set to the one being overtaken</param>
127134
/// <returns>true if is overtaking a thumbstick direction already depressed</returns>
@@ -151,7 +158,7 @@ namespace sds
151158
}
152159
return false;
153160
}
154-
void DoOvertaking(KeyboardKeyMap &detail)
161+
void DoOvertaking(KeyboardKeyMap &detail) noexcept
155162
{
156163
SendTheKey(detail, false, InpType::KEYUP);
157164
}

XMapLib/MapFunctions.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,20 @@
22
#include <map>
33
namespace sds::Utilities::MapFunctions
44
{
5-
/// <summary>
6-
/// Verifies that the key value is in the map{T,H} and sets a reference arg to the value
7-
/// if found.
8-
/// </summary>
5+
/// <summary>Verifies that the key value is in the map{T,H} and sets a reference arg to the value if found.</summary>
96
/// <param name="keyValue">key value to check</param>
107
/// <param name="curMap">map of T,H to check the key</param>
118
/// <param name="retVal">will be set to the value the key points to, if found</param>
129
/// <returns>true if found, false otherwise</returns>
1310
template<class T, class H>
1411
bool IsInMap(const T keyValue, const std::map<T, H>& curMap, H& retVal)
1512
{
16-
auto it = curMap.find(keyValue);
13+
const auto it = curMap.find(keyValue);
1714
if(it != curMap.end())
1815
{
1916
retVal = it->second;
2017
return true;
2118
}
22-
else
23-
{
24-
return false;
25-
}
19+
return false;
2620
}
2721
}

0 commit comments

Comments
 (0)