Skip to content

Commit 68139a2

Browse files
authoredNov 12, 2020
Revert "Replace MyEventReceiver KeyList with std::unordered_set" (#10622)
This reverts commit 787561b.
1 parent adffef2 commit 68139a2

File tree

3 files changed

+111
-64
lines changed

3 files changed

+111
-64
lines changed
 

‎src/client/inputhandler.cpp

+22-26
Original file line numberDiff line numberDiff line change
@@ -112,23 +112,23 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
112112
// Remember whether each key is down or up
113113
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
114114
const KeyPress &keyCode = event.KeyInput;
115-
if (keysListenedFor.count(keyCode)) {
115+
if (keysListenedFor[keyCode]) {
116116
// If the key is being held down then the OS may
117117
// send a continuous stream of keydown events.
118118
// In this case, we don't want to let this
119119
// stream reach the application as it will cause
120120
// certain actions to repeat constantly.
121121
if (event.KeyInput.PressedDown) {
122122
if (!IsKeyDown(keyCode)) {
123-
keyWasDown.insert(keyCode);
124-
keyWasPressed.insert(keyCode);
123+
keyWasDown.set(keyCode);
124+
keyWasPressed.set(keyCode);
125125
}
126-
keyIsDown.insert(keyCode);
126+
keyIsDown.set(keyCode);
127127
} else {
128128
if (IsKeyDown(keyCode))
129-
keyWasReleased.insert(keyCode);
129+
keyWasReleased.set(keyCode);
130130

131-
keyIsDown.erase(keyCode);
131+
keyIsDown.unset(keyCode);
132132
}
133133

134134
return true;
@@ -153,36 +153,36 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
153153
switch (event.MouseInput.Event) {
154154
case EMIE_LMOUSE_PRESSED_DOWN:
155155
key = "KEY_LBUTTON";
156-
keyIsDown.insert(key);
157-
keyWasDown.insert(key);
158-
keyWasPressed.insert(key);
156+
keyIsDown.set(key);
157+
keyWasDown.set(key);
158+
keyWasPressed.set(key);
159159
break;
160160
case EMIE_MMOUSE_PRESSED_DOWN:
161161
key = "KEY_MBUTTON";
162-
keyIsDown.insert(key);
163-
keyWasDown.insert(key);
164-
keyWasPressed.insert(key);
162+
keyIsDown.set(key);
163+
keyWasDown.set(key);
164+
keyWasPressed.set(key);
165165
break;
166166
case EMIE_RMOUSE_PRESSED_DOWN:
167167
key = "KEY_RBUTTON";
168-
keyIsDown.insert(key);
169-
keyWasDown.insert(key);
170-
keyWasPressed.insert(key);
168+
keyIsDown.set(key);
169+
keyWasDown.set(key);
170+
keyWasPressed.set(key);
171171
break;
172172
case EMIE_LMOUSE_LEFT_UP:
173173
key = "KEY_LBUTTON";
174-
keyIsDown.erase(key);
175-
keyWasReleased.insert(key);
174+
keyIsDown.unset(key);
175+
keyWasReleased.set(key);
176176
break;
177177
case EMIE_MMOUSE_LEFT_UP:
178178
key = "KEY_MBUTTON";
179-
keyIsDown.erase(key);
180-
keyWasReleased.insert(key);
179+
keyIsDown.unset(key);
180+
keyWasReleased.set(key);
181181
break;
182182
case EMIE_RMOUSE_LEFT_UP:
183183
key = "KEY_RBUTTON";
184-
keyIsDown.erase(key);
185-
keyWasReleased.insert(key);
184+
keyIsDown.unset(key);
185+
keyWasReleased.set(key);
186186
break;
187187
case EMIE_MOUSE_WHEEL:
188188
mouse_wheel += event.MouseInput.Wheel;
@@ -235,11 +235,7 @@ void RandomInputHandler::step(float dtime)
235235
i.counter -= dtime;
236236
if (i.counter < 0.0) {
237237
i.counter = 0.1 * Rand(1, i.time_max);
238-
KeyPress k = getKeySetting(i.key.c_str());
239-
if (keydown.count(k))
240-
keydown.erase(k);
241-
else
242-
keydown.insert(k);
238+
keydown.toggle(getKeySetting(i.key.c_str()));
243239
}
244240
}
245241
{

‎src/client/inputhandler.h

+89-19
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2121

2222
#include "irrlichttypes_extrabloated.h"
2323
#include "joystick_controller.h"
24+
#include <list>
2425
#include "keycode.h"
2526
#include "renderingengine.h"
26-
#include <unordered_set>
2727

2828
#ifdef HAVE_TOUCHSCREENGUI
2929
#include "gui/touchscreengui.h"
@@ -61,32 +61,98 @@ struct KeyCache
6161
InputHandler *handler;
6262
};
6363

64+
class KeyList : private std::list<KeyPress>
65+
{
66+
typedef std::list<KeyPress> super;
67+
typedef super::iterator iterator;
68+
typedef super::const_iterator const_iterator;
69+
70+
virtual const_iterator find(const KeyPress &key) const
71+
{
72+
const_iterator f(begin());
73+
const_iterator e(end());
74+
75+
while (f != e) {
76+
if (*f == key)
77+
return f;
78+
79+
++f;
80+
}
81+
82+
return e;
83+
}
84+
85+
virtual iterator find(const KeyPress &key)
86+
{
87+
iterator f(begin());
88+
iterator e(end());
89+
90+
while (f != e) {
91+
if (*f == key)
92+
return f;
93+
94+
++f;
95+
}
96+
97+
return e;
98+
}
99+
100+
public:
101+
void clear() { super::clear(); }
102+
103+
void set(const KeyPress &key)
104+
{
105+
if (find(key) == end())
106+
push_back(key);
107+
}
108+
109+
void unset(const KeyPress &key)
110+
{
111+
iterator p(find(key));
112+
113+
if (p != end())
114+
erase(p);
115+
}
116+
117+
void toggle(const KeyPress &key)
118+
{
119+
iterator p(this->find(key));
120+
121+
if (p != end())
122+
erase(p);
123+
else
124+
push_back(key);
125+
}
126+
127+
bool operator[](const KeyPress &key) const { return find(key) != end(); }
128+
};
129+
64130
class MyEventReceiver : public IEventReceiver
65131
{
66132
public:
67133
// This is the one method that we have to implement
68134
virtual bool OnEvent(const SEvent &event);
69135

70-
bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown.count(keyCode); }
136+
bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; }
71137

72138
// Checks whether a key was down and resets the state
73139
bool WasKeyDown(const KeyPress &keyCode)
74140
{
75-
bool b = keyWasDown.count(keyCode);
141+
bool b = keyWasDown[keyCode];
76142
if (b)
77-
keyWasDown.erase(keyCode);
143+
keyWasDown.unset(keyCode);
78144
return b;
79145
}
80146

81147
// Checks whether a key was just pressed. State will be cleared
82148
// in the subsequent iteration of Game::processPlayerInteraction
83-
bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed.count(keycode); }
149+
bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; }
84150

85151
// Checks whether a key was just released. State will be cleared
86152
// in the subsequent iteration of Game::processPlayerInteraction
87-
bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased.count(keycode); }
153+
bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; }
88154

89-
void listenForKey(const KeyPress &keyCode) { keysListenedFor.insert(keyCode); }
155+
void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); }
90156
void dontListenForKeys() { keysListenedFor.clear(); }
91157

92158
s32 getMouseWheel()
@@ -132,20 +198,24 @@ class MyEventReceiver : public IEventReceiver
132198
#endif
133199

134200
private:
135-
//! The current state of keys
136-
std::unordered_set<KeyPress> keyIsDown;
201+
// The current state of keys
202+
KeyList keyIsDown;
137203

138-
//! Whether a key was down
139-
std::unordered_set<KeyPress> keyWasDown;
204+
// Whether a key was down
205+
KeyList keyWasDown;
140206

141-
//! Whether a key has just been pressed
142-
std::unordered_set<KeyPress> keyWasPressed;
207+
// Whether a key has just been pressed
208+
KeyList keyWasPressed;
143209

144-
//! Whether a key has just been released
145-
std::unordered_set<KeyPress> keyWasReleased;
210+
// Whether a key has just been released
211+
KeyList keyWasReleased;
146212

147-
//! List of keys we listen for
148-
std::unordered_set<KeyPress> keysListenedFor;
213+
// List of keys we listen for
214+
// TODO perhaps the type of this is not really
215+
// performant as KeyList is designed for few but
216+
// often changing keys, and keysListenedFor is expected
217+
// to change seldomly but contain lots of keys.
218+
KeyList keysListenedFor;
149219
};
150220

151221
class InputHandler
@@ -277,7 +347,7 @@ class RandomInputHandler : public InputHandler
277347
return true;
278348
}
279349

280-
virtual bool isKeyDown(GameKeyType k) { return keydown.count(keycache.key[k]); }
350+
virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; }
281351
virtual bool wasKeyDown(GameKeyType k) { return false; }
282352
virtual bool wasKeyPressed(GameKeyType k) { return false; }
283353
virtual bool wasKeyReleased(GameKeyType k) { return false; }
@@ -292,7 +362,7 @@ class RandomInputHandler : public InputHandler
292362
s32 Rand(s32 min, s32 max);
293363

294364
private:
295-
std::unordered_set<KeyPress> keydown;
365+
KeyList keydown;
296366
v2s32 mousepos;
297367
v2s32 mousespeed;
298368
};

‎src/client/keycode.h

-19
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2424
#include <IEventReceiver.h>
2525
#include <string>
2626

27-
class KeyPress;
28-
namespace std
29-
{
30-
template <> struct hash<KeyPress>;
31-
}
32-
3327
/* A key press, consisting of either an Irrlicht keycode
3428
or an actual char */
3529

3630
class KeyPress
3731
{
3832
public:
39-
friend struct std::hash<KeyPress>;
40-
4133
KeyPress() = default;
4234

4335
KeyPress(const char *name);
@@ -63,17 +55,6 @@ class KeyPress
6355
std::string m_name = "";
6456
};
6557

66-
namespace std
67-
{
68-
template <> struct hash<KeyPress>
69-
{
70-
size_t operator()(const KeyPress &key) const
71-
{
72-
return key.Key;
73-
}
74-
};
75-
}
76-
7758
extern const KeyPress EscapeKey;
7859
extern const KeyPress CancelKey;
7960

0 commit comments

Comments
 (0)
Please sign in to comment.