I am looking for advice on my input component. There is no real problem with it yet, but I am just getting started on everything and want to know if there is any obvious problems with it, plus I was looking for advice on a design question of it.
The design question refers to whether or not I should treat alt, ctrl, and shift like mod keys or separate keys. When I thought about it at first, it made sense. This way gives more shortcut key possibilities (i.e. macros in games like Ultima Online) or I assumed how games like Counter Strike control run/walk (if shift is held with move key, and it affects how much speed the move gives) but the more I think about it, in Counter Strike, it could be the modifying key is just another key affecting a total speed. So I'm at a point in which I wonder if my efforts to make the modded key functions aren't really the right way to go.
Second, in my class, I use std::map<key,function<void()>>
where key is a struct that contains mods/scancode values. Then it finds the associated function from the map and calls it if it exists. I don't know if it is wise to search a map every time the key is pressed down, held, and released. Is this something I should concern myself with at this point in development? Should I assume it works fine, move on, and find it slow later to change it then?
TL;DR care about modded keys in input class? Are there any obvious problems with my design?
#ifndef __INPUT_H__
#define __INPUT_H__
#include <SDL.h>
#include <iostream>
#include <map>
#include <vector>
#include <functional>
#include "Vector2f.h"
#include "MouseButton.h"
struct key {
SDL_Scancode code;
Uint16 kmod;
key() {
code = SDL_SCANCODE_UNKNOWN;
kmod = KMOD_NONE;
}
key(SDL_Scancode kcode, Uint16 kkmod) {
code = kcode;
kmod = kkmod;
}
key(const key& source) {
code = source.code;
kmod = source.kmod;
}
bool operator<(const key& rhs) const {
return std::tie( code,kmod ) < std::tie( rhs.code, rhs.kmod );
}
bool operator==(const key& rhs) const {
return std::tie( code,kmod ) == std::tie( rhs.code, rhs.kmod );
}
};
class Input {
private:
std::vector<key> HeldKeys;
std::map<key,std::function<void()>> OnDownFuncs;
std::map<key,std::function<void()>> OnHoldFuncs;
std::map<key,std::function<void()>> OnUpFuncs;
MouseButton LClick; //unimplemented yet
MouseButton RClick; //unimplemented yet
const int NUM_KEYCODES;
public:
Input() : NUM_KEYCODES(256) {
HeldKeys.clear();
}
void update();
void KeyDown(SDL_KeyboardEvent key);
void KeyUp(SDL_KeyboardEvent key);
void MouseDown(int key);
void MouseUp(int key);
void RegOnKeyDown(SDL_Scancode key, Uint16 kmod, std::function<void()> func);
void RegOnKeyHold(SDL_Scancode key, Uint16 kmod, std::function<void()> func);
void RegOnKeyUp(SDL_Scancode key, Uint16 kmod, std::function<void()> func);
};
#endif
Input.cpp
#include "Input.h"
void Input::update() {
for( std::vector<key>::iterator it = HeldKeys.begin(); it != HeldKeys.end(); it++ ) {
std::map<key,std::function<void()>>::iterator func = OnHoldFuncs.find(*it);
if( func != OnHoldFuncs.end() )
func->second();
}
}
void Input::KeyDown(SDL_KeyboardEvent pkey) {
if( pkey.repeat == 1 )
return;
key nkey(pkey.keysym.scancode,pkey.keysym.mod);
std::map<key,std::function<void()>>::iterator func = OnDownFuncs.find(nkey);
if( func != OnDownFuncs.end() )
func->second();
else
std::cout << "unknown key " << pkey.keysym.scancode << " is pressed" << std::endl;
func = OnHoldFuncs.find(nkey);
if( func != OnHoldFuncs.end() )
HeldKeys.push_back(nkey);
return;
}
void Input::KeyUp(SDL_KeyboardEvent pkey) {
key nkey(pkey.keysym.scancode,pkey.keysym.mod);
std::map<key,std::function<void()>>::iterator func = OnUpFuncs.find(nkey);
if( func != OnUpFuncs.end() )
func->second();
else
std::cout << "unknown key " << pkey.keysym.scancode << " is released" << std::endl;
for( std::vector<key>::iterator it = HeldKeys.begin(); it != HeldKeys.end(); it++ ) {
if(*it == nkey) {
HeldKeys.erase(it);
break;
}
}
}
void Input::MouseDown(int key) {
}
void Input::MouseUp(int key) {
}
void Input::RegOnKeyDown(SDL_Scancode code, Uint16 kmod, std::function<void()> func) {
key tkey;
tkey.code = code;
tkey.kmod = kmod;
OnDownFuncs.insert(std::pair<key,std::function<void()>>(tkey,func));
return;
}
void Input::RegOnKeyHold(SDL_Scancode code, Uint16 kmod, std::function<void()> func) {
key tkey;
tkey.code = code;
tkey.kmod = kmod;
OnHoldFuncs.insert(std::pair<key,std::function<void()>>(tkey,func));
return;
}
void Input::RegOnKeyUp(SDL_Scancode code, Uint16 kmod, std::function<void()> func) {
key tkey;
tkey.code = code;
tkey.kmod = kmod;
OnUpFuncs.insert(std::pair<key,std::function<void()>>(tkey,func));
return;
}