Hey.
My input system has a GetKey() method that returns a key in a map. Simple enough.
However, I want to know if the key is not available - be it a typo, or misuse of wording, or something else.
I am the only person working on this project; would it be a good idea to simply set some compile time throw to see if it catches one? Is this even possible?
What I'm meaning is:
if(entry is not found) { throw something("couldn't find key"); exit(); }
Rather than an approach of
if(entry is not found) { try and compensate somehow and continue }
And then go through the code and find where I've made a mistake. Of course, for a large project I would want real error handling like the second. But I can just get rid of these errors, since there's no modding. But I'm the only one working, so is this probably the easiest way to do it?
Well, it's this or make some kind of BLANK key and check it every query.
EDIT: I am using strings as my keys, so no translate functions would be easy.
Double EDIT: I bind commands (strings) to keys (wrapper over an enum value). It means it's more understandable to check if "move_left" has been pressed than if keyCode::A has been, as well as being more changeable.
|
||||
When debugging, it's great to throw an exception. When the user has the program and encounters something that you missed, it's not; you might want to silently log the error, or ignore the call and just return from the function, but you probably don't want to throw an exception and stop everything just because there's a bug in your code unless it's a showstopper. C and C++ support assertions via assert.h; I like to use those, and this would be a good place for one. For example, at the top of the GetKey method, do an assert that the key is found. However this is also a good place for using an enum rather than a char or whatever you're currently using. That way, the programmer must use a value from the enum and there's not really a possible way to feed it anything else. |
|||||||||
|
You can't do anything like look up a string key from a hash table at compile time, because that would involve executing code. However you CAN use something like static_assert (Visual Studio or Boost)to do things like check for enum values. static_assert lets you check any const expression, and can be very useful for setting up certain safeguards. For instance if you had two enum structures that are independent but should be related to each other, you can static_assert that the two enum values are the same. You can also static assert on sizeof, offsetof, and other compile-time functions. |
|||||||||
|
Why not make a translate function that always gets called? That way you'll only have to look in one place. If you, instead of actual keycodes, use an enum the compiler will complain by default when you enter an invalid code) - the translate function can convert that enum to its actual keycode and is in charge of what input is valid. Edited to add: abstracting the input out to one location will also make it a lot easier to make your keyboard layout redefinable. |
|||||
|
While it's more elegant to transform the problem so that you can utilize the static checking mechanisms of your language or existing tools (e.g. enum + lint or higher warning setting), you can roll your own tool if you're not able to do this.
...then you might be able to use a simple It's possible to get some false positives and false negatives here. Too many, and maintaining the tool starts to become more of an effort than it is worth. We have used a tool like this for a localization system, checking that all of our "string ids" actually match up to real strings. These string ids are used in c, cpp, and lua sources, and also in json, xml, and other "baked" forms of data. It's not perfect; it gives up when the string id was piecewise constructed by earlier code rather than being a literal. One other nifty thing you can do with this is turn more expensive string literals into less expensive unique IDs or hashes as a pre-precompile step. If you don't control your build process this can get to be a pain, and if the tool is slow at all you get slow builds (which I loathe with the burning passion of a thousand fiery suns -- but that's another answer)... but you may already be doing some pre-preprocessing for e.g. swig or similar tools. This has the advantage of mandating a consistent syntax, and it'll fail your build if there's anything wrong. (There are definitely tools out there that do this latter thing; look around a bit!) |
|||
|
if(entry not found) { }
and handle it like method 2? That way the debugger will stop at the line when an invalid key is pressed and even provide you with information about all the function calls that led up to it. – 5ound Aug 2 at 19:12