I have a wxWidgets application. This is the first, main module. The second module is an openGL engine. It's a model-view-(controller) structure, where application is the view (and the controller), while the engine is the model.
This is the problem that I need to solve:
I need to take input from the application, and have the engine change itself based on that data (move the camera, highlight the selection, substitute one mesh/texture with another, etc).
The constraint is that the system cannot have the key bindings hardcoded, they need to be editable by the user without having to restart the application.
This is what I figured out so far:
Application will have an InputHandler class. This class will contain a map that has keycode as the key, and a struct that will contain a function pointer and a list of pointers to it's arguments as a value. It will also have a single method that will use that data to construct a complete method call when a keycode is received.
This design makes it possible to change the key bindings dynamically and will remove the need for huge if..else trees or giant switch..case statements.
But now we have a problem within the engine. All those methods are the interface between the engine and the application. This means that most of them would invoke some internal methods to do actual work (a moveCamera method would just access the internal camera class and invoke the translate command with the same argument it was given). If I don't do it this way, the application have more access to engine than it should.
This design has two levels of abstraction, first one when receiving a keycode and using it to form and call a method and second where the called method would really just be an interface for the application that would call other method(s) that do the real work.
At this point, I'd like to note that I've spent several hours rewriting this question and modifying the design, noticing new flaws as I was trying to explain it. This is the best I could come up with. Finally, my questions are:
Is this a good way to achieve what I have written in bold above? What flaws do you see in the design? Is there a way for me to fix them? Would another design altogether be better suited for the task? How would you approach this problem?