Leviathan  0.8.0.0
Leviathan game engine
Key.h
Go to the documentation of this file.
1 // Leviathan Game Engine
2 // Copyright (c) 2012-2018 Henri Hyyryläinen
3 #pragma once
4 #include "Define.h"
5 // ------------------------------------ //
7 #include "Exceptions.h"
8 #include "GUI/KeyMapping.h"
10 #include "Window.h"
11 
12 enum KEYSPECIAL {
18  // = 0x20
19  // 0x40
20  // 0x80 // first byte full
21  // 0x100
22  // 0x200
23  // 0x400
24  // 0x800
25  // 0x1000
26  // 0x2000
27  // 0x4000
28  // 0x8000 // second byte full (int range might stop here(
29  // 0x10000
30  // 0x20000
31  // 0x40000
32  // 0x80000
33  // 0x100000
34  // 0x200000
35  // 0x400000
36  // 0x800000 // third byte full
37  // 0x1000000
38  // 0x2000000
39  // 0x4000000
40  // 0x8000000
41  // 0x10000000
42  // 0x20000000
43  // 0x40000000
44  // 0x80000000 // fourth byte full (will need QWORD here)
45  // 0x100000000
46 };
47 
48 namespace Leviathan {
49 
50 template<class T>
51 class Key {
52 public:
53  inline Key<T>()
54  {
55  Extras = 0;
56  Character = (T)0;
57  }
58  inline Key<T>(const T& character, const short& additional)
59  {
60  Extras = additional;
61  Character = character;
62  }
63  inline ~Key() {}
64 
65  inline bool Match(const Key<T>& other, bool strict = false) const
66  {
67  if(other.Character != this->Character)
68  return false;
69  if(strict) {
70  if(other.Extras != this->Extras)
71  return false;
72  } else {
73 
74  if((Extras & KEYSPECIAL_SHIFT) && !(other.Extras & KEYSPECIAL_SHIFT)) {
75  return false;
76  }
77  if((Extras & KEYSPECIAL_ALT) && !(other.Extras & KEYSPECIAL_ALT)) {
78  return false;
79  }
80  if((Extras & KEYSPECIAL_CTRL) && !(other.Extras & KEYSPECIAL_CTRL)) {
81  return false;
82  }
83  }
84  return true;
85  }
86 
87  inline std::string GenerateStringMessage(const int& style = 0)
88  {
89  // create a string that represents this key //
90  if(style == 0) {
91  // debug string //
92  std::string resultstr = "Key[" + Convert::ToString((char)Character) + "]=";
93 
94  resultstr += Convert::ToString<T>(Character);
95  resultstr += "(0x" + Convert::ToHexadecimalString<T>(Character) + ")+";
96 
97  return resultstr;
98  }
99  // various styles from which a key can be easily parsed //
100  DEBUG_BREAK;
101  return "error";
102  }
103 
104  inline bool Match(const T& chara, const short& additional, bool strict = false) const
105  {
106  return Match(Key<T>(chara, additional), strict);
107  }
108 
109  inline bool Match(const T& chara) const
110  {
111  if(chara != this->Character)
112  return false;
113  return true;
114  }
115 
116 
117  T GetCharacter() const
118  {
119  return Character;
120  }
121  short GetAdditional() const
122  {
123  return Extras;
124  }
125 
126  void Set(const T& character, const short& additional)
127  {
128  Character = character;
129  Extras = additional;
130  }
131 
132  void SetAdditional(const short& additional)
133  {
134 
135  Extras = additional;
136  }
137 
138  static void DeConstructSpecial(short keyspes, bool& Shift, bool& Alt, bool& Ctrl)
139  {
140 
141  if(keyspes & KEYSPECIAL_SHIFT)
142  Shift = true;
143  if(keyspes & KEYSPECIAL_ALT)
144  Alt = true;
145  if(keyspes & KEYSPECIAL_CTRL)
146  Ctrl = true;
147  }
148 
150  static Key<T> GenerateKeyFromString(const std::string& representation)
151  {
152  if(representation.size() == 0) {
153  // empty, nothing to do //
154  return Key<T>((T)0, 0);
155  }
156 
157  StringIterator itr(representation);
158 
159  std::unique_ptr<std::string> str;
160 
161  // Allow plus key
162  if(representation[0] == '+') {
163  itr.MoveToNext();
164  str = std::make_unique<std::string>("+");
165  } else {
166 
167  str = itr.GetUntilNextCharacterOrAll<std::string>('+');
168  }
169 
170  if(!str) {
171 
172  throw Leviathan::InvalidArgument("Key: can't parse: " + representation);
173  }
174 
175  T character;
176 
177  // Only upcase single letters as long key codes have also lowercase letters
178  if(str->length() <= 1) {
179 
180  auto converted = StringOperations::ToUpperCase<std::string>(*str);
181 
182  character = Leviathan::KeyMapping::ConvertStringToKeyCode(converted);
183 
184  } else {
185 
186  // Detect things like "Keypad +" and make them work
187  const auto pos = itr.GetPosition();
188  if((pos + 1 >= representation.length() && pos < representation.length() &&
189  representation[pos] == '+') ||
190  // This is things like "Keypad ++SHIFT"
191  (pos + 1 <= representation.length() && representation[pos] == '+' &&
192  representation[pos + 1] == '+')) {
193 
194  character = Leviathan::KeyMapping::ConvertStringToKeyCode(*str + "+");
195  } else {
196 
198  }
199  }
200 
201  short special = 0;
202 
203  while((str = itr.GetUntilNextCharacterOrAll<std::string>('+')) && (str->size() > 0)) {
204 
205  if(StringOperations::CompareInsensitive(*str, std::string("ALT"))) {
206  special |= KEYSPECIAL_ALT;
207  }
208  if(StringOperations::CompareInsensitive(*str, std::string("SHIFT"))) {
209  special |= KEYSPECIAL_SHIFT;
210  }
211  if(StringOperations::CompareInsensitive(*str, std::string("CTRL"))) {
212  special |= KEYSPECIAL_CTRL;
213  }
214  if(StringOperations::CompareInsensitive(*str, std::string("WIN")) ||
215  StringOperations::CompareInsensitive(*str, std::string("META")) ||
216  StringOperations::CompareInsensitive(*str, std::string("SUPER")) ||
217  StringOperations::CompareInsensitive(*str, std::string("GUI"))) {
218  special |= KEYSPECIAL_SUPER;
219  }
220  }
221 
222  return Key<T>(character, special);
223  }
224 
225  std::string GenerateStringFromKey()
226  {
227  // First the actual key value //
228  auto resultstr = Leviathan::KeyMapping::ConvertKeyCodeToString(Character);
229 
230  // Add special modifiers //
231  if(Extras & KEYSPECIAL_ALT)
232  resultstr += "+ALT";
233  if(Extras & KEYSPECIAL_CTRL)
234  resultstr += "+CTRL";
235  if(Extras & KEYSPECIAL_SHIFT)
236  resultstr += "+SHIFT";
237  if(Extras & KEYSPECIAL_SUPER)
238  resultstr += "+META";
239  // Result is done //
240  return resultstr;
241  }
242 
243 private:
244  short Extras;
245  T Character;
246 };
247 
249 template<typename KeyType>
250 inline bool MatchesAnyKeyInSet(const std::vector<Key<KeyType>> keys, const KeyType& chara,
251  const short& additional, bool strict = false)
252 {
253  for(const auto& key : keys)
254  if(key.Match(chara, additional, strict))
255  return true;
256  return false;
257 }
258 
259 // This is the most likely type //
261 
262 } // namespace Leviathan
bool Match(const T &chara) const
Definition: Key.h:109
std::string GenerateStringFromKey()
Definition: Key.h:225
DLLEXPORT std::string ConvertKeyCodeToString(const int32_t &code)
Definition: KeyMapping.cpp:52
bool MoveToNext()
Skips the current character and moves to the next.
Key< int32_t > GKey
Definition: Key.h:260
void SetAdditional(const short &additional)
Definition: Key.h:132
T GetCharacter() const
Definition: Key.h:117
KEYSPECIAL
Definition: Key.h:12
std::unique_ptr< RStrType > GetUntilNextCharacterOrAll(int charactertolookfor, int specialflags=0)
Gets characters until a character or all remaining characters.
static Key< T > GenerateKeyFromString(const std::string &representation)
https://wiki.libsdl.org/SDL_Keycode for key names
Definition: Key.h:150
DLLEXPORT int32_t ConvertStringToKeyCode(const std::string &str)
Definition: KeyMapping.cpp:38
bool Match(const Key< T > &other, bool strict=false) const
Definition: Key.h:65
Iterator class for getting parts of a string.
static void DeConstructSpecial(short keyspes, bool &Shift, bool &Alt, bool &Ctrl)
Definition: Key.h:138
std::string GenerateStringMessage(const int &style=0)
Definition: Key.h:87
static std::string ToString(const T &val)
Definition: Convert.h:72
short GetAdditional() const
Definition: Key.h:121
static bool CompareInsensitive(const StringTypeN &data, const StringTypeN &second)
size_t GetPosition()
Returns the current reading position.
bool Match(const T &chara, const short &additional, bool strict=false) const
Definition: Key.h:104
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
void Set(const T &character, const short &additional)
Definition: Key.h:126
bool MatchesAnyKeyInSet(const std::vector< Key< KeyType >> keys, const KeyType &chara, const short &additional, bool strict=false)
Helper for checking multiple keys.
Definition: Key.h:250