Luanti 5.16.0-dev
Loading...
Searching...
No Matches
keycode.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5#pragma once
6
7#include "irrlichttypes.h"
8#include "keys.h"
9#include <Keycodes.h>
10#include <IEventReceiver.h>
11#include <string>
12#include <variant>
13#include <vector>
14
15/* A key press, consisting of a scancode or a keycode.
16 * This fits into 64 bits, so prefer passing this by value.
17*/
19{
20public:
21 enum class InputType {
22 KEYBOARD, // Keyboard input (scancodes)
23 MOUSE_BUTTON, // Mouse button input
24 GAME_ACTION, // GameKeyType input passed by touchscreen buttons
25 };
26
27 KeyPress() = default;
28
29 KeyPress(const std::string &name);
30
31 KeyPress(const SEvent::SKeyInput &in);
32
33 KeyPress(const SEvent::SMouseInput &in);
34
35 KeyPress(GameKeyType key) : value(key) {}
36
37 // Get a string representation that is suitable for use in minetest.conf
38 std::string sym() const;
39
40 // Get a human-readable string representation
41 std::string name() const;
42
43 // Get the scancode or 0 is one is not available
44 u32 getScancode() const
45 {
46 if (auto pv = getIf<InputType::KEYBOARD>())
47 return *pv;
48 return 0;
49 }
50
51 bool operator==(KeyPress o) const {
52 return value == o.value;
53 }
54 bool operator!=(KeyPress o) const {
55 return !(*this == o);
56 }
57
58 // Used for e.g. std::set
59 bool operator<(KeyPress o) const {
60 return value < o.value;
61 }
62
63 // Get the type of input
65 return static_cast<InputType>(value.index());
66 }
67
68 // Check whether the keypress is valid
69 operator bool() const;
70
71 static KeyPress getSpecialKey(const std::string &name);
72
73private:
74 // The same data type may be used for different variants, so this should be indexed using InputType.
75 // The get, getIf, and emplace methods are wrappers for their std::variant counterparts. This allows using
76 // InputType enum values instead of numeric indices.
77 using value_type = std::variant<u32, u32, GameKeyType>;
78
79 template<InputType I>
80 using value_alternative_t = std::variant_alternative_t<static_cast<size_t>(I), value_type>;
81
82 template<InputType I>
83 bool loadUnsignedFromPrefix(const std::string &name, const std::string &prefix);
84 bool loadFromScancode(const std::string &name);
85 void loadFromKey(EKEY_CODE keycode, wchar_t keychar);
86
88
89 template<InputType I>
91 return std::get<static_cast<size_t>(I)>(value);
92 }
93
94 template<InputType I>
95 std::add_pointer_t<const value_alternative_t<I>> getIf() const {
96 return std::get_if<static_cast<size_t>(I)>(&value);
97 }
98
99 template<InputType I>
101 value.emplace<static_cast<size_t>(I)>(newValue);
102 }
103
104 friend std::hash<KeyPress>;
105};
106
107template <>
108struct std::hash<KeyPress>
109{
110 size_t operator()(KeyPress kp) const noexcept {
111 return std::hash<KeyPress::value_type>{}(kp.value);
112 }
113};
114
115// Global defines for convenience
116// This implementation defers creation of the objects to make sure that the
117// IrrlichtDevice is initialized.
118#define EscapeKey KeyPress::getSpecialKey("KEY_ESCAPE")
119
120// Key configuration getter
121// Note that the reference may be invalidated by a next call to getKeySetting
122// or a related function, so the value should either be used immediately or
123// copied elsewhere before calling this again.
124const std::vector<KeyPress> &getKeySetting(const std::string &settingname);
125
126// Check whether the key setting includes a key.
127bool keySettingHasMatch(const std::string &settingname, KeyPress kp);
128
129// Clear fast lookup cache
130void clearKeyCache();
Definition keycode.h:19
void loadFromKey(EKEY_CODE keycode, wchar_t keychar)
Definition keycode.cpp:277
u32 getScancode() const
Definition keycode.h:44
KeyPress(GameKeyType key)
Definition keycode.h:35
value_alternative_t< I > get() const
Definition keycode.h:90
std::add_pointer_t< const value_alternative_t< I > > getIf() const
Definition keycode.h:95
bool loadFromScancode(const std::string &name)
static KeyPress getSpecialKey(const std::string &name)
Definition keycode.cpp:396
std::string sym() const
Definition keycode.cpp:319
std::string name() const
Definition keycode.cpp:331
std::variant_alternative_t< static_cast< size_t >(I), value_type > value_alternative_t
Definition keycode.h:80
bool operator!=(KeyPress o) const
Definition keycode.h:54
std::variant< u32, u32, GameKeyType > value_type
Definition keycode.h:77
bool operator==(KeyPress o) const
Definition keycode.h:51
bool operator<(KeyPress o) const
Definition keycode.h:59
InputType getType() const
Definition keycode.h:64
value_type value
Definition keycode.h:87
bool loadUnsignedFromPrefix(const std::string &name, const std::string &prefix)
Definition keycode.cpp:369
InputType
Definition keycode.h:21
@ GAME_ACTION
Definition keycode.h:24
@ MOUSE_BUTTON
Definition keycode.h:23
@ KEYBOARD
Definition keycode.h:22
KeyPress()=default
void emplace(value_alternative_t< I > newValue)
Definition keycode.h:100
const std::vector< KeyPress > & getKeySetting(const std::string &settingname)
Definition keycode.cpp:411
bool keySettingHasMatch(const std::string &settingname, KeyPress kp)
Definition keycode.cpp:429
void clearKeyCache()
Definition keycode.cpp:435
KeyType::T GameKeyType
Definition keys.h:109
size_t operator()(KeyPress kp) const noexcept
Definition keycode.h:110