bindbc-sdl
bindbc-sdl copied to clipboard
SDL2 - SDL_Keycode
For key bindings provided by the user of my engine, my code uses:
to!SDL_Keycode("SDLK_a");
Up until version 1.2.4 this worked since SDL_Keycode was defined as:
enum SDL_Keycode { }
However, in later versions of the bindings, the code changed to:
alias SDL_KeyCode = uint;
enum : SDL_KeyCode{ }
Now this automated conversion from string containing the enum member name to enum member is not possible anymore:
std.conv.ConvException@/usr/include/dmd/phobos/std/conv.d(2533): Unexpected 'S' when converting from type string to type int
Is there an easy way to restore the original behaviour?
My engine uses a config file to allow the user to configure SDL_Keycode (and SDL_EventType) to allow rebind-able keys (on runtime) to be coupled to in engine events, e.g.:
SDLK_ESCAPE, Quit, SDL_QUIT, QUIT
SDLK_UP, CameraMove, SDL_USEREVENT, FORWARD_3D
SDLK_DOWN, CameraMove, SDL_USEREVENT, BACKWARD_3D
SDLK_LEFT, CameraMove, SDL_USEREVENT, LEFT_3D
SDLK_RIGHT, CameraMove, SDL_USEREVENT, RIGHT_3D
SDLK_PAGEUP, CameraMove, SDL_USEREVENT, UP_3D
SDLK_PAGEDOWN, CameraMove, SDL_USEREVENT, DOWN_3D
That's the disadvantage of my current approach. The SDL3 bindings will have both C and D-style enums, which will solve this kind of problem.
You can emulate what you were doing before with something like this:
enum strToKeycodeCT = (){
SDL_Keycode[string] ret;
static foreach(member; __traits(allMembers, sdl.keycode)){
static if(is(typeof(__traits(getMember, sdl.keycode, member)) == SDL_Keycode)){
ret[member] = __traits(getMember, sdl.keycode, member);
}
}
return ret;
}();
immutable strToKeycode = strToKeycodeCT;
void main(){
import std.stdio: writeln;
writeln(strToKeycode["SDLK_a"]);
writeln(strToKeycode["SDLK_ESCAPE"]);
}
Technically this will include a key for SDLK_SCANCODE_MASK
, but you can manually exclude it if it bothers you.