#include <iostream>
#include <stack>
using namespace std;
struct Virtual
{
virtual ~Virtual() { }
};
struct Context;
struct State : Virtual
{
virtual void Handle(Context& data) { Update(data); };
virtual void Entry(Context& data);
virtual void Update(Context& data) { }
virtual void Exit(Context& data);
};
struct Normal : State
{
void Handle(Context& data);
};
struct StandBy : Normal
{
void Handle(Context& data);
void Entry(Context& data);
void Update(Context& data);
};
struct Move : Normal
{
void Handle(Context& data);
void Entry(Context& data);
void Update(Context& data);
};
struct Shoot : State
{
void Handle(Context& data);
void Entry(Context& data);
void Update(Context& data);
};
struct Context
{
StandBy standBy_;
Move move_;
Shoot shoot_;
stack<State*> active_;
char input = 0;
Context() { active_.push(&standBy_); }
void Handle() { active_.top()->Handle(*this); }
} context;
enum : char
{
FIRE = 'f',
STOP = 's',
MOVE = 'm',
};
void State::Entry(Context& data)
{
data.active_.push(this);
}
void State::Exit(Context& data)
{
data.active_.pop();
}
void Normal::Handle(Context& data)
{
if (FIRE == data.input)
{
data.shoot_.Entry(data);
}
else
{
State::Handle(data);
}
}
void StandBy::Handle(Context& data)
{
if (MOVE == data.input)
{
Exit(data);
data.move_.Entry(data);
}
else
{
Normal::Handle(data);
}
}
void StandBy::Entry(Context& data)
{
Normal::Entry(data);
cout << __FUNCTION__ << endl;
}
void StandBy::Update(Context& data)
{
Normal::Update(data);
cout << __FUNCTION__ << endl;
}
void Move::Handle(Context& data)
{
if (STOP == data.input)
{
Exit(data);
data.standBy_.Entry(data);
}
else
{
Normal::Handle(data);
}
}
void Move::Entry(Context& data)
{
Normal::Entry(data);
cout << __FUNCTION__ << endl;
}
void Move::Update(Context& data)
{
Normal::Update(data);
cout << __FUNCTION__ << endl;
}
void Shoot::Handle(Context& data)
{
if (FIRE != data.input)
{
Exit(data);
}
else
{
Update(data);
}
}
void Shoot::Entry(Context& data)
{
State::Entry(data);
cout << __FUNCTION__ << endl;
}
void Shoot::Update(Context& data)
{
State::Update(data);
cout << __FUNCTION__ << endl;
}
int main()
{
for (;;)
{
cin >> context.input;
context.Handle();
}
}