summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Robinson <robinsonvincent89@gmail.com>2020-09-23 10:12:20 -0700
committerGitHub <noreply@github.com>2020-09-23 19:12:20 +0200
commit787561b29afdbc78769f68c2f5c4f2cff1b32340 (patch)
treedc97c2b4be4cf6f9291de43aefe2b940728dfff9
parent34e3ede8eeb05e193e64ba3d055fc67959d87d86 (diff)
downloadminetest-787561b29afdbc78769f68c2f5c4f2cff1b32340.tar.gz
minetest-787561b29afdbc78769f68c2f5c4f2cff1b32340.tar.bz2
minetest-787561b29afdbc78769f68c2f5c4f2cff1b32340.zip
Replace MyEventReceiver KeyList with std::unordered_set (#10419)
-rw-r--r--src/client/inputhandler.cpp48
-rw-r--r--src/client/inputhandler.h108
-rw-r--r--src/client/keycode.h19
3 files changed, 64 insertions, 111 deletions
diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp
index 608a405a8..ee3e37ae9 100644
--- a/src/client/inputhandler.cpp
+++ b/src/client/inputhandler.cpp
@@ -112,7 +112,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
const KeyPress &keyCode = event.KeyInput;
- if (keysListenedFor[keyCode]) {
+ if (keysListenedFor.count(keyCode)) {
// If the key is being held down then the OS may
// send a continuous stream of keydown events.
// In this case, we don't want to let this
@@ -120,15 +120,15 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
// certain actions to repeat constantly.
if (event.KeyInput.PressedDown) {
if (!IsKeyDown(keyCode)) {
- keyWasDown.set(keyCode);
- keyWasPressed.set(keyCode);
+ keyWasDown.insert(keyCode);
+ keyWasPressed.insert(keyCode);
}
- keyIsDown.set(keyCode);
+ keyIsDown.insert(keyCode);
} else {
if (IsKeyDown(keyCode))
- keyWasReleased.set(keyCode);
+ keyWasReleased.insert(keyCode);
- keyIsDown.unset(keyCode);
+ keyIsDown.erase(keyCode);
}
return true;
@@ -153,36 +153,36 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
switch (event.MouseInput.Event) {
case EMIE_LMOUSE_PRESSED_DOWN:
key = "KEY_LBUTTON";
- keyIsDown.set(key);
- keyWasDown.set(key);
- keyWasPressed.set(key);
+ keyIsDown.insert(key);
+ keyWasDown.insert(key);
+ keyWasPressed.insert(key);
break;
case EMIE_MMOUSE_PRESSED_DOWN:
key = "KEY_MBUTTON";
- keyIsDown.set(key);
- keyWasDown.set(key);
- keyWasPressed.set(key);
+ keyIsDown.insert(key);
+ keyWasDown.insert(key);
+ keyWasPressed.insert(key);
break;
case EMIE_RMOUSE_PRESSED_DOWN:
key = "KEY_RBUTTON";
- keyIsDown.set(key);
- keyWasDown.set(key);
- keyWasPressed.set(key);
+ keyIsDown.insert(key);
+ keyWasDown.insert(key);
+ keyWasPressed.insert(key);
break;
case EMIE_LMOUSE_LEFT_UP:
key = "KEY_LBUTTON";
- keyIsDown.unset(key);
- keyWasReleased.set(key);
+ keyIsDown.erase(key);
+ keyWasReleased.insert(key);
break;
case EMIE_MMOUSE_LEFT_UP:
key = "KEY_MBUTTON";
- keyIsDown.unset(key);
- keyWasReleased.set(key);
+ keyIsDown.erase(key);
+ keyWasReleased.insert(key);
break;
case EMIE_RMOUSE_LEFT_UP:
key = "KEY_RBUTTON";
- keyIsDown.unset(key);
- keyWasReleased.set(key);
+ keyIsDown.erase(key);
+ keyWasReleased.insert(key);
break;
case EMIE_MOUSE_WHEEL:
mouse_wheel += event.MouseInput.Wheel;
@@ -235,7 +235,11 @@ void RandomInputHandler::step(float dtime)
i.counter -= dtime;
if (i.counter < 0.0) {
i.counter = 0.1 * Rand(1, i.time_max);
- keydown.toggle(getKeySetting(i.key.c_str()));
+ KeyPress k = getKeySetting(i.key.c_str());
+ if (keydown.count(k))
+ keydown.erase(k);
+ else
+ keydown.insert(k);
}
}
{
diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h
index def147a82..885f34e05 100644
--- a/src/client/inputhandler.h
+++ b/src/client/inputhandler.h
@@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_extrabloated.h"
#include "joystick_controller.h"
-#include <list>
#include "keycode.h"
#include "renderingengine.h"
+#include <unordered_set>
#ifdef HAVE_TOUCHSCREENGUI
#include "gui/touchscreengui.h"
@@ -61,98 +61,32 @@ struct KeyCache
InputHandler *handler;
};
-class KeyList : private std::list<KeyPress>
-{
- typedef std::list<KeyPress> super;
- typedef super::iterator iterator;
- typedef super::const_iterator const_iterator;
-
- virtual const_iterator find(const KeyPress &key) const
- {
- const_iterator f(begin());
- const_iterator e(end());
-
- while (f != e) {
- if (*f == key)
- return f;
-
- ++f;
- }
-
- return e;
- }
-
- virtual iterator find(const KeyPress &key)
- {
- iterator f(begin());
- iterator e(end());
-
- while (f != e) {
- if (*f == key)
- return f;
-
- ++f;
- }
-
- return e;
- }
-
-public:
- void clear() { super::clear(); }
-
- void set(const KeyPress &key)
- {
- if (find(key) == end())
- push_back(key);
- }
-
- void unset(const KeyPress &key)
- {
- iterator p(find(key));
-
- if (p != end())
- erase(p);
- }
-
- void toggle(const KeyPress &key)
- {
- iterator p(this->find(key));
-
- if (p != end())
- erase(p);
- else
- push_back(key);
- }
-
- bool operator[](const KeyPress &key) const { return find(key) != end(); }
-};
-
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent &event);
- bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; }
+ bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown.count(keyCode); }
// Checks whether a key was down and resets the state
bool WasKeyDown(const KeyPress &keyCode)
{
- bool b = keyWasDown[keyCode];
+ bool b = keyWasDown.count(keyCode);
if (b)
- keyWasDown.unset(keyCode);
+ keyWasDown.erase(keyCode);
return b;
}
// Checks whether a key was just pressed. State will be cleared
// in the subsequent iteration of Game::processPlayerInteraction
- bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; }
+ bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed.count(keycode); }
// Checks whether a key was just released. State will be cleared
// in the subsequent iteration of Game::processPlayerInteraction
- bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; }
+ bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased.count(keycode); }
- void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); }
+ void listenForKey(const KeyPress &keyCode) { keysListenedFor.insert(keyCode); }
void dontListenForKeys() { keysListenedFor.clear(); }
s32 getMouseWheel()
@@ -198,24 +132,20 @@ public:
#endif
private:
- // The current state of keys
- KeyList keyIsDown;
+ //! The current state of keys
+ std::unordered_set<KeyPress> keyIsDown;
- // Whether a key was down
- KeyList keyWasDown;
+ //! Whether a key was down
+ std::unordered_set<KeyPress> keyWasDown;
- // Whether a key has just been pressed
- KeyList keyWasPressed;
+ //! Whether a key has just been pressed
+ std::unordered_set<KeyPress> keyWasPressed;
- // Whether a key has just been released
- KeyList keyWasReleased;
+ //! Whether a key has just been released
+ std::unordered_set<KeyPress> keyWasReleased;
- // List of keys we listen for
- // TODO perhaps the type of this is not really
- // performant as KeyList is designed for few but
- // often changing keys, and keysListenedFor is expected
- // to change seldomly but contain lots of keys.
- KeyList keysListenedFor;
+ //! List of keys we listen for
+ std::unordered_set<KeyPress> keysListenedFor;
};
class InputHandler
@@ -347,7 +277,7 @@ public:
return true;
}
- virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; }
+ virtual bool isKeyDown(GameKeyType k) { return keydown.count(keycache.key[k]); }
virtual bool wasKeyDown(GameKeyType k) { return false; }
virtual bool wasKeyPressed(GameKeyType k) { return false; }
virtual bool wasKeyReleased(GameKeyType k) { return false; }
@@ -362,7 +292,7 @@ public:
s32 Rand(s32 min, s32 max);
private:
- KeyList keydown;
+ std::unordered_set<KeyPress> keydown;
v2s32 mousepos;
v2s32 mousespeed;
};
diff --git a/src/client/keycode.h b/src/client/keycode.h
index 7036705d1..263b722c7 100644
--- a/src/client/keycode.h
+++ b/src/client/keycode.h
@@ -24,12 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IEventReceiver.h>
#include <string>
+class KeyPress;
+namespace std
+{
+ template <> struct hash<KeyPress>;
+}
+
/* A key press, consisting of either an Irrlicht keycode
or an actual char */
class KeyPress
{
public:
+ friend struct std::hash<KeyPress>;
+
KeyPress() = default;
KeyPress(const char *name);
@@ -55,6 +63,17 @@ protected:
std::string m_name = "";
};
+namespace std
+{
+ template <> struct hash<KeyPress>
+ {
+ size_t operator()(const KeyPress &key) const
+ {
+ return key.Key;
+ }
+ };
+}
+
extern const KeyPress EscapeKey;
extern const KeyPress CancelKey;