I have an application that has multiple states, with each state responding to input differently.
The initial implementation was done with a big switch statement, which I refactored using the state pattern (at least, I think it's the state pattern. I'm kind of new to using design patterns, so I tend to get them confused) -
class App {
public:
static App * getInstance();
void addState(int state_id, AppState * state) { _states[state_id] = state; }
void setCurrentState(int state_id) { _current_state = _states[state_id]; }
private:
App()
~App();
std::map<int, AppState *> _states;
AppState * _current_state;
static App * _instance;
}
class AppState {
public:
virtual void handleInput() = 0;
virtual ~AppState();
protected:
AppState();
}
Currently, each state is polling the OS for input, and acting accordingly. This means each concrete state has a huge switch statement with a case for each valid keypress. Some cases call functions, and other cases issue state changes by using App::setCurrentState(newstate). The catch is that a key that does something in one state may not do anything (or in rare circumstances, may do something different) in another state.
Okay, I think that's the pertinent background. Here's the actual question(s) -
First, what's the best way to eliminate the huge switch statements in the concrete states? This question suggests the command pattern, but I don't understand how I would use it here. Can someone help explain it, or suggest another solution?
As a side note, I've considered (and am not opposed to) the idea of letting the App class do the polling of the OS, and then pass inputs to _current_state->handleInput. In fact, something tells me that I'll want to do this as part of the refactoring. I just haven't done it yet.
Second, state changes are made by calling App::setCurrentState(newstate). I realize that this is akin to using globals, but I'm not sure of a better way to do it. My main goal is to be able to add states without modifying the App class. Suggestions would be welcome here as well.