Sign in to follow this  

Key assignment system

This topic is 2668 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I created a system to allow me to assign commands to different keys. Since the Direct Input method of retrieving the keyboard state used an array of chars to store the result, I used an array of member function pointers of the same size (as the char[]) so that I could match up a key press with a function call.

Doing it this way then allows me to change the assignments at run time.

I don't care about return types (all the commands return void). However, to pass parameters, I am using void pointers.

I often get told void pointers are the devil and completely break type safety.

At the moment, the only way I can think to get rid of them in this case is to use a heirarchy of EventParameter objects in place of the void pointers.

Is there a better way to achieve the same effect?

My code:


class input{

public:

input(commands *);

private:

commands * cmd_obj;

static const int numberofkeys = 256;
char buffer[numberofkeys];

typedef void (commands::*FPt_commands)(void*);
FPt_commands assigned_keys[numberofkeys];

};

void input::init_Keyboard(HWND hWnd){

assigned_keys[17] = &commands::move_forward; // DIK_W
assigned_keys[31] = &commands::move_backward; // DIK_S

}

void input::update_Keyboard(){

if(dinputdev_keyboard){

// get keyboard state
hr = dinputdev_keyboard->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);

for(int p = 0;p<numberofkeys;p++){

if(buffer[p]!=0){

int * speed = 3;

void* vPtr = speed;

(cmd_obj->*(assigned_keys[p]))(vPtr) ;

}

}
}


}

______in commands.ccp______

void commands::move_forward(void * vPtr){

int * speed = (int)vPtr;

}

Share this post


Link to post
Share on other sites
Those are pretty much your two options -- using void* pointers and casting to an assumed type, or using a base parameter type and sub-classing the various actual parameters your callbacks need and casting to the right sub-class. The latter approach has at least some measure of type-safety since you have to cast to related types (without going through major hoops), and if worse comes to worst you can also use RTTI and enforce run-time checks on parameter type. The sub-classing isn't that big a deal either, since with void* pointers you often end up creating parameter types anyway, just without the common base. Double dispatch may also work for you.

Share this post


Link to post
Share on other sites

This topic is 2668 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this