Вы можете просто сохранить их в стеке, хотя это немного сложнее:)
Тем не менее, это забавное решение, так что пошли. Основополагающим принципом является игра с декораторами и изменчивость. Пример кода:
State state1, state2; // creates a state
Event KEY_UP;
Event KEY_DOWN;
Transition t0(state1, KEY_UP, state2);
Transition t1(state2, KEY_DOWN, state1);
Как это работает?
Вместо state1
, являющегося «простым» объектом, он будет немного более запутанным. Что-то вроде:
struct State;
struct StateImpl {
StateImpl(char const* n): name(n) {}
char const* name;
};
struct StateNode {
StateNode(Event e, State const& s, StateNode const* n):
event(e), state(s), next(n) {}
Event event;
State const& destination;
StateNode const* next;
};
struct State {
State(char const* name):
me(0), impl(name) {}
StateNode const* me;
StateImpl impl;
};
А затем мы определяем Transition
:
struct Transition {
Transition(State& origin, Event e, State const& destination):
node(e, destination, origin.me)
{
origin.me = node;
}
StateNode node;
};
Неофициально, мы строим односвязный список, с головой в State
. Мы обновляем голову каждый раз, когда добавляем переход.
При возникновении события необходимо пройти по этому списку, пока либо не встретится событие и, соответственно, не будет отправлено соответствующее сообщение, либо пока не будет достигнут нулевой указатель, указывающий, что событие не должно быть получено в этом состоянии.