mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Replace MyEventReceiver KeyList with std::unordered_set (#10419)
This commit is contained in:
parent
34e3ede8ee
commit
787561b29a
@ -112,7 +112,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
|
|||||||
// Remember whether each key is down or up
|
// Remember whether each key is down or up
|
||||||
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
|
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
|
||||||
const KeyPress &keyCode = event.KeyInput;
|
const KeyPress &keyCode = event.KeyInput;
|
||||||
if (keysListenedFor[keyCode]) {
|
if (keysListenedFor.count(keyCode)) {
|
||||||
// If the key is being held down then the OS may
|
// If the key is being held down then the OS may
|
||||||
// send a continuous stream of keydown events.
|
// send a continuous stream of keydown events.
|
||||||
// In this case, we don't want to let this
|
// 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.
|
// certain actions to repeat constantly.
|
||||||
if (event.KeyInput.PressedDown) {
|
if (event.KeyInput.PressedDown) {
|
||||||
if (!IsKeyDown(keyCode)) {
|
if (!IsKeyDown(keyCode)) {
|
||||||
keyWasDown.set(keyCode);
|
keyWasDown.insert(keyCode);
|
||||||
keyWasPressed.set(keyCode);
|
keyWasPressed.insert(keyCode);
|
||||||
}
|
}
|
||||||
keyIsDown.set(keyCode);
|
keyIsDown.insert(keyCode);
|
||||||
} else {
|
} else {
|
||||||
if (IsKeyDown(keyCode))
|
if (IsKeyDown(keyCode))
|
||||||
keyWasReleased.set(keyCode);
|
keyWasReleased.insert(keyCode);
|
||||||
|
|
||||||
keyIsDown.unset(keyCode);
|
keyIsDown.erase(keyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -153,36 +153,36 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
|
|||||||
switch (event.MouseInput.Event) {
|
switch (event.MouseInput.Event) {
|
||||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||||
key = "KEY_LBUTTON";
|
key = "KEY_LBUTTON";
|
||||||
keyIsDown.set(key);
|
keyIsDown.insert(key);
|
||||||
keyWasDown.set(key);
|
keyWasDown.insert(key);
|
||||||
keyWasPressed.set(key);
|
keyWasPressed.insert(key);
|
||||||
break;
|
break;
|
||||||
case EMIE_MMOUSE_PRESSED_DOWN:
|
case EMIE_MMOUSE_PRESSED_DOWN:
|
||||||
key = "KEY_MBUTTON";
|
key = "KEY_MBUTTON";
|
||||||
keyIsDown.set(key);
|
keyIsDown.insert(key);
|
||||||
keyWasDown.set(key);
|
keyWasDown.insert(key);
|
||||||
keyWasPressed.set(key);
|
keyWasPressed.insert(key);
|
||||||
break;
|
break;
|
||||||
case EMIE_RMOUSE_PRESSED_DOWN:
|
case EMIE_RMOUSE_PRESSED_DOWN:
|
||||||
key = "KEY_RBUTTON";
|
key = "KEY_RBUTTON";
|
||||||
keyIsDown.set(key);
|
keyIsDown.insert(key);
|
||||||
keyWasDown.set(key);
|
keyWasDown.insert(key);
|
||||||
keyWasPressed.set(key);
|
keyWasPressed.insert(key);
|
||||||
break;
|
break;
|
||||||
case EMIE_LMOUSE_LEFT_UP:
|
case EMIE_LMOUSE_LEFT_UP:
|
||||||
key = "KEY_LBUTTON";
|
key = "KEY_LBUTTON";
|
||||||
keyIsDown.unset(key);
|
keyIsDown.erase(key);
|
||||||
keyWasReleased.set(key);
|
keyWasReleased.insert(key);
|
||||||
break;
|
break;
|
||||||
case EMIE_MMOUSE_LEFT_UP:
|
case EMIE_MMOUSE_LEFT_UP:
|
||||||
key = "KEY_MBUTTON";
|
key = "KEY_MBUTTON";
|
||||||
keyIsDown.unset(key);
|
keyIsDown.erase(key);
|
||||||
keyWasReleased.set(key);
|
keyWasReleased.insert(key);
|
||||||
break;
|
break;
|
||||||
case EMIE_RMOUSE_LEFT_UP:
|
case EMIE_RMOUSE_LEFT_UP:
|
||||||
key = "KEY_RBUTTON";
|
key = "KEY_RBUTTON";
|
||||||
keyIsDown.unset(key);
|
keyIsDown.erase(key);
|
||||||
keyWasReleased.set(key);
|
keyWasReleased.insert(key);
|
||||||
break;
|
break;
|
||||||
case EMIE_MOUSE_WHEEL:
|
case EMIE_MOUSE_WHEEL:
|
||||||
mouse_wheel += event.MouseInput.Wheel;
|
mouse_wheel += event.MouseInput.Wheel;
|
||||||
@ -235,7 +235,11 @@ void RandomInputHandler::step(float dtime)
|
|||||||
i.counter -= dtime;
|
i.counter -= dtime;
|
||||||
if (i.counter < 0.0) {
|
if (i.counter < 0.0) {
|
||||||
i.counter = 0.1 * Rand(1, i.time_max);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "joystick_controller.h"
|
#include "joystick_controller.h"
|
||||||
#include <list>
|
|
||||||
#include "keycode.h"
|
#include "keycode.h"
|
||||||
#include "renderingengine.h"
|
#include "renderingengine.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
#ifdef HAVE_TOUCHSCREENGUI
|
||||||
#include "gui/touchscreengui.h"
|
#include "gui/touchscreengui.h"
|
||||||
@ -61,98 +61,32 @@ struct KeyCache
|
|||||||
InputHandler *handler;
|
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
|
class MyEventReceiver : public IEventReceiver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This is the one method that we have to implement
|
// This is the one method that we have to implement
|
||||||
virtual bool OnEvent(const SEvent &event);
|
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
|
// Checks whether a key was down and resets the state
|
||||||
bool WasKeyDown(const KeyPress &keyCode)
|
bool WasKeyDown(const KeyPress &keyCode)
|
||||||
{
|
{
|
||||||
bool b = keyWasDown[keyCode];
|
bool b = keyWasDown.count(keyCode);
|
||||||
if (b)
|
if (b)
|
||||||
keyWasDown.unset(keyCode);
|
keyWasDown.erase(keyCode);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks whether a key was just pressed. State will be cleared
|
// Checks whether a key was just pressed. State will be cleared
|
||||||
// in the subsequent iteration of Game::processPlayerInteraction
|
// 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
|
// Checks whether a key was just released. State will be cleared
|
||||||
// in the subsequent iteration of Game::processPlayerInteraction
|
// 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(); }
|
void dontListenForKeys() { keysListenedFor.clear(); }
|
||||||
|
|
||||||
s32 getMouseWheel()
|
s32 getMouseWheel()
|
||||||
@ -198,24 +132,20 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The current state of keys
|
//! The current state of keys
|
||||||
KeyList keyIsDown;
|
std::unordered_set<KeyPress> keyIsDown;
|
||||||
|
|
||||||
// Whether a key was down
|
//! Whether a key was down
|
||||||
KeyList keyWasDown;
|
std::unordered_set<KeyPress> keyWasDown;
|
||||||
|
|
||||||
// Whether a key has just been pressed
|
//! Whether a key has just been pressed
|
||||||
KeyList keyWasPressed;
|
std::unordered_set<KeyPress> keyWasPressed;
|
||||||
|
|
||||||
// Whether a key has just been released
|
//! Whether a key has just been released
|
||||||
KeyList keyWasReleased;
|
std::unordered_set<KeyPress> keyWasReleased;
|
||||||
|
|
||||||
// List of keys we listen for
|
//! List of keys we listen for
|
||||||
// TODO perhaps the type of this is not really
|
std::unordered_set<KeyPress> keysListenedFor;
|
||||||
// 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InputHandler
|
class InputHandler
|
||||||
@ -347,7 +277,7 @@ public:
|
|||||||
return true;
|
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 wasKeyDown(GameKeyType k) { return false; }
|
||||||
virtual bool wasKeyPressed(GameKeyType k) { return false; }
|
virtual bool wasKeyPressed(GameKeyType k) { return false; }
|
||||||
virtual bool wasKeyReleased(GameKeyType k) { return false; }
|
virtual bool wasKeyReleased(GameKeyType k) { return false; }
|
||||||
@ -362,7 +292,7 @@ public:
|
|||||||
s32 Rand(s32 min, s32 max);
|
s32 Rand(s32 min, s32 max);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeyList keydown;
|
std::unordered_set<KeyPress> keydown;
|
||||||
v2s32 mousepos;
|
v2s32 mousepos;
|
||||||
v2s32 mousespeed;
|
v2s32 mousespeed;
|
||||||
};
|
};
|
||||||
|
@ -24,12 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <IEventReceiver.h>
|
#include <IEventReceiver.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
class KeyPress;
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <> struct hash<KeyPress>;
|
||||||
|
}
|
||||||
|
|
||||||
/* A key press, consisting of either an Irrlicht keycode
|
/* A key press, consisting of either an Irrlicht keycode
|
||||||
or an actual char */
|
or an actual char */
|
||||||
|
|
||||||
class KeyPress
|
class KeyPress
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
friend struct std::hash<KeyPress>;
|
||||||
|
|
||||||
KeyPress() = default;
|
KeyPress() = default;
|
||||||
|
|
||||||
KeyPress(const char *name);
|
KeyPress(const char *name);
|
||||||
@ -55,6 +63,17 @@ protected:
|
|||||||
std::string m_name = "";
|
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 EscapeKey;
|
||||||
extern const KeyPress CancelKey;
|
extern const KeyPress CancelKey;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user