Use EnumArray for Key or Scancode-indexed arrays

This commit is contained in:
kimci86 2023-12-17 18:38:54 +01:00 committed by Chris Thrasher
parent faaceb5b5b
commit d2f4452fc8
5 changed files with 35 additions and 41 deletions

View File

@ -63,7 +63,7 @@ sf::Vector2i mousePos; // current mouse position
std::vector<int> fileDescriptors; // list of open file descriptors for /dev/input std::vector<int> fileDescriptors; // list of open file descriptors for /dev/input
sf::priv::EnumArray<sf::Mouse::Button, bool, sf::Mouse::ButtonCount> mouseMap{}; // track whether mouse buttons are down sf::priv::EnumArray<sf::Mouse::Button, bool, sf::Mouse::ButtonCount> mouseMap{}; // track whether mouse buttons are down
std::vector<bool> keyMap(sf::Keyboard::KeyCount, false); // track whether keys are down sf::priv::EnumArray<sf::Keyboard::Key, bool, sf::Keyboard::KeyCount> keyMap{}; // track whether keys are down
int touchFd = -1; // file descriptor we have seen MT events on; assumes only 1 int touchFd = -1; // file descriptor we have seen MT events on; assumes only 1
std::vector<TouchSlot> touchSlots; // track the state of each touch "slot" std::vector<TouchSlot> touchSlots; // track the state of each touch "slot"
@ -427,7 +427,7 @@ bool eventProcess(sf::Event& event)
event.key.shift = shiftDown(); event.key.shift = shiftDown();
event.key.system = systemDown(); event.key.system = systemDown();
keyMap[static_cast<std::size_t>(kb)] = inputEvent.value; keyMap[kb] = inputEvent.value;
if (special && inputEvent.value) if (special && inputEvent.value)
doDeferredText = special; doDeferredText = special;
@ -578,7 +578,7 @@ bool isKeyPressed(Keyboard::Key key)
return false; return false;
update(); update();
return keyMap[static_cast<std::size_t>(key)]; return keyMap[key];
} }

View File

@ -30,6 +30,7 @@
#include <SFML/Window/Unix/KeySymToUnicodeMapping.hpp> #include <SFML/Window/Unix/KeySymToUnicodeMapping.hpp>
#include <SFML/Window/Unix/KeyboardImpl.hpp> #include <SFML/Window/Unix/KeyboardImpl.hpp>
#include <SFML/System/EnumArray.hpp>
#include <SFML/System/String.hpp> #include <SFML/System/String.hpp>
#include <SFML/System/Utf.hpp> #include <SFML/System/Utf.hpp>
@ -37,6 +38,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <array>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
@ -46,10 +48,10 @@
namespace namespace
{ {
const KeyCode nullKeyCode = 0; const KeyCode nullKeyCode = 0;
const int maxKeyCode = 256; const int maxKeyCode = 256;
KeyCode scancodeToKeycode[sf::Keyboard::ScancodeCount]; ///< Mapping of SFML scancode to X11 KeyCode sf::priv::EnumArray<sf::Keyboard::Scancode, KeyCode, sf::Keyboard::ScancodeCount> scancodeToKeycode; ///< Mapping of SFML scancode to X11 KeyCode
sf::Keyboard::Scancode keycodeToScancode[maxKeyCode]; ///< Mapping of X11 KeyCode to SFML scancode std::array<sf::Keyboard::Scancode, maxKeyCode> keycodeToScancode; ///< Mapping of X11 KeyCode to SFML scancode
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool isValidKeycode(KeyCode keycode) bool isValidKeycode(KeyCode keycode)
@ -460,11 +462,8 @@ void ensureMapping()
return; return;
// Phase 1: Initialize mappings with default values // Phase 1: Initialize mappings with default values
for (auto& keycode : scancodeToKeycode) scancodeToKeycode.fill(nullKeyCode);
keycode = nullKeyCode; keycodeToScancode.fill(sf::Keyboard::Scan::Unknown);
for (auto& scancode : keycodeToScancode)
scancode = sf::Keyboard::Scan::Unknown;
// Phase 2: Get XKB names with key code // Phase 2: Get XKB names with key code
Display* display = sf::priv::openDisplay(); Display* display = sf::priv::openDisplay();
@ -493,9 +492,9 @@ void ensureMapping()
scancode = mappedScancode->second; scancode = mappedScancode->second;
if (scancode != sf::Keyboard::Scan::Unknown) if (scancode != sf::Keyboard::Scan::Unknown)
scancodeToKeycode[static_cast<std::size_t>(scancode)] = static_cast<KeyCode>(keycode); scancodeToKeycode[scancode] = static_cast<KeyCode>(keycode);
keycodeToScancode[keycode] = scancode; keycodeToScancode[static_cast<KeyCode>(keycode)] = scancode;
} }
XkbFreeNames(descriptor, XkbKeyNamesMask, True); XkbFreeNames(descriptor, XkbKeyNamesMask, True);
@ -508,11 +507,10 @@ void ensureMapping()
{ {
scancode = translateKeyCode(display, static_cast<KeyCode>(keycode)); scancode = translateKeyCode(display, static_cast<KeyCode>(keycode));
if (scancode != sf::Keyboard::Scan::Unknown && if (scancode != sf::Keyboard::Scan::Unknown && scancodeToKeycode[scancode] == nullKeyCode)
scancodeToKeycode[static_cast<std::size_t>(scancode)] == nullKeyCode) scancodeToKeycode[scancode] = static_cast<KeyCode>(keycode);
scancodeToKeycode[static_cast<std::size_t>(scancode)] = static_cast<KeyCode>(keycode);
keycodeToScancode[keycode] = scancode; keycodeToScancode[static_cast<KeyCode>(keycode)] = scancode;
} }
} }
@ -528,7 +526,7 @@ KeyCode scancodeToKeyCode(sf::Keyboard::Scancode code)
ensureMapping(); ensureMapping();
if (code != sf::Keyboard::Scan::Unknown) if (code != sf::Keyboard::Scan::Unknown)
return scancodeToKeycode[static_cast<std::size_t>(code)]; return scancodeToKeycode[code];
return nullKeyCode; return nullKeyCode;
} }
@ -563,7 +561,7 @@ KeyCode keyToKeyCode(sf::Keyboard::Key key)
// Fallback for when XKeysymToKeycode cannot tell the KeyCode for XK_Alt_R // Fallback for when XKeysymToKeycode cannot tell the KeyCode for XK_Alt_R
if (key == sf::Keyboard::RAlt) if (key == sf::Keyboard::RAlt)
return scancodeToKeycode[static_cast<std::size_t>(sf::Keyboard::Scan::RAlt)]; return scancodeToKeycode[sf::Keyboard::Scan::RAlt];
return nullKeyCode; return nullKeyCode;
} }

View File

@ -28,13 +28,14 @@
#include <SFML/Window/InputImpl.hpp> #include <SFML/Window/InputImpl.hpp>
#include <SFML/Window/Window.hpp> #include <SFML/Window/Window.hpp>
#include <SFML/System/EnumArray.hpp>
#include <SFML/System/String.hpp> #include <SFML/System/String.hpp>
#include <SFML/System/Win32/WindowsHeader.hpp> #include <SFML/System/Win32/WindowsHeader.hpp>
namespace namespace
{ {
sf::Keyboard::Scancode keyToScancodeMapping[sf::Keyboard::KeyCount]; ///< Mapping from Key to Scancode sf::priv::EnumArray<sf::Keyboard::Key, sf::Keyboard::Scancode, sf::Keyboard::KeyCount> keyToScancodeMapping; ///< Mapping from Key to Scancode
sf::Keyboard::Key scancodeToKeyMapping[sf::Keyboard::ScancodeCount]; ///< Mapping from Scancode to Key sf::priv::EnumArray<sf::Keyboard::Scancode, sf::Keyboard::Key, sf::Keyboard::ScancodeCount> scancodeToKeyMapping; ///< Mapping from Scancode to Key
sf::Keyboard::Key virtualKeyToSfKey(UINT virtualKey) sf::Keyboard::Key virtualKeyToSfKey(UINT virtualKey)
{ {
@ -520,11 +521,8 @@ void ensureMappings()
return; return;
// Phase 1: Initialize mappings with default values // Phase 1: Initialize mappings with default values
for (auto& scancode : keyToScancodeMapping) keyToScancodeMapping.fill(sf::Keyboard::Scan::Unknown);
scancode = sf::Keyboard::Scan::Unknown; scancodeToKeyMapping.fill(sf::Keyboard::Key::Unknown);
for (auto& key : scancodeToKeyMapping)
key = sf::Keyboard::Unknown;
// Phase 2: Translate scancode to virtual code to key names // Phase 2: Translate scancode to virtual code to key names
for (unsigned int i = 0; i < sf::Keyboard::ScancodeCount; ++i) for (unsigned int i = 0; i < sf::Keyboard::ScancodeCount; ++i)
@ -534,7 +532,7 @@ void ensureMappings()
const sf::Keyboard::Key key = virtualKeyToSfKey(virtualKey); const sf::Keyboard::Key key = virtualKeyToSfKey(virtualKey);
if (key != sf::Keyboard::Unknown && keyToScancodeMapping[key] == sf::Keyboard::Scan::Unknown) if (key != sf::Keyboard::Unknown && keyToScancodeMapping[key] == sf::Keyboard::Scan::Unknown)
keyToScancodeMapping[key] = scan; keyToScancodeMapping[key] = scan;
scancodeToKeyMapping[static_cast<std::size_t>(scan)] = key; scancodeToKeyMapping[scan] = key;
} }
isMappingInitialized = true; isMappingInitialized = true;
@ -578,7 +576,7 @@ Keyboard::Key localize(Keyboard::Scancode code)
ensureMappings(); ensureMappings();
return scancodeToKeyMapping[static_cast<std::size_t>(code)]; return scancodeToKeyMapping[code];
} }

View File

@ -286,10 +286,10 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
IOHIDManagerRef m_manager{}; ///< Underlying HID Manager IOHIDManagerRef m_manager{}; ///< Underlying HID Manager
IOHIDElements m_keys[Keyboard::ScancodeCount]; ///< All the keys on any connected keyboard EnumArray<Keyboard::Scancode, IOHIDElements, Keyboard::ScancodeCount> m_keys; ///< All the keys on any connected keyboard
Keyboard::Scancode m_keyToScancodeMapping[Keyboard::KeyCount]{}; ///< Mapping from Key to Scancode EnumArray<Keyboard::Key, Keyboard::Scancode, Keyboard::KeyCount> m_keyToScancodeMapping{}; ///< Mapping from Key to Scancode
Keyboard::Key m_scancodeToKeyMapping[Keyboard::ScancodeCount]{}; ///< Mapping from Scancode to Key EnumArray<Keyboard::Scancode, Keyboard::Key, Keyboard::ScancodeCount> m_scancodeToKeyMapping{}; ///< Mapping from Scancode to Key
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// m_keys' index corresponds to sf::Keyboard::Scancode enum. /// m_keys' index corresponds to sf::Keyboard::Scancode enum.

View File

@ -562,7 +562,7 @@ bool HIDInputManager::isKeyPressed(Keyboard::Key key)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool HIDInputManager::isKeyPressed(Keyboard::Scancode code) bool HIDInputManager::isKeyPressed(Keyboard::Scancode code)
{ {
return (code != Keyboard::Scan::Unknown) && isPressed(m_keys[static_cast<std::size_t>(code)]); return (code != Keyboard::Scan::Unknown) && isPressed(m_keys[code]);
} }
@ -572,7 +572,7 @@ Keyboard::Key HIDInputManager::localize(Keyboard::Scancode code)
if (code == Keyboard::Scan::Unknown) if (code == Keyboard::Scan::Unknown)
return Keyboard::Unknown; return Keyboard::Unknown;
return m_scancodeToKeyMapping[static_cast<std::size_t>(code)]; return m_scancodeToKeyMapping[code];
} }
@ -795,7 +795,7 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
if (code != Keyboard::Scan::Unknown) if (code != Keyboard::Scan::Unknown)
{ {
CFRetain(key); CFRetain(key);
m_keys[static_cast<std::size_t>(code)].push_back(key); m_keys[code].push_back(key);
} }
} }
@ -804,10 +804,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
void HIDInputManager::buildMappings() void HIDInputManager::buildMappings()
{ {
// Reset the mappings // Reset the mappings
for (auto& scancode : m_keyToScancodeMapping) m_keyToScancodeMapping.fill(Keyboard::Scan::Unknown);
scancode = Keyboard::Scan::Unknown; m_scancodeToKeyMapping.fill(Keyboard::Key::Unknown);
for (auto& key : m_scancodeToKeyMapping)
key = Keyboard::Unknown;
// Get the current keyboard layout // Get the current keyboard layout
TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource(); TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource();
@ -899,7 +897,7 @@ void HIDInputManager::buildMappings()
// Register the bi-mapping // Register the bi-mapping
if (m_keyToScancodeMapping[code] == Keyboard::Scan::Unknown) if (m_keyToScancodeMapping[code] == Keyboard::Scan::Unknown)
m_keyToScancodeMapping[code] = scan; m_keyToScancodeMapping[code] = scan;
m_scancodeToKeyMapping[static_cast<std::size_t>(scan)] = code; m_scancodeToKeyMapping[scan] = code;
} }
CFRelease(tis); CFRelease(tis);