#include <iostream>
using namespace std;
#include "Macho.hpp"
namespace Microwave {
TOPSTATE(Top) {
struct Box {
Box() : myCookingTime(0) {}
void printTimer() { cout << " Timer set to " << myCookingTime << " minutes" << endl; }
void incrementTimer() { ++myCookingTime; }
void decrementTimer() { -- myCookingTime; }
void resetTimer() { myCookingTime = 0; }
int getRemainingTime() { return myCookingTime; }
private:
int myCookingTime;
};
STATE(Top)
virtual void open() {}
virtual void close() {}
virtual void minute() {} virtual void start() {} virtual void stop() {} virtual void tick() {}
private:
void init();
};
SUBSTATE(Disabled, Top) {
STATE(Disabled)
void close();
private:
void entry();
void exit();
};
SUBSTATE(Operational, Top) {
STATE(Operational)
DEEPHISTORY()
void open();
void stop();
private:
void init();
};
SUBSTATE(Idle, Operational) {
STATE(Idle)
void minute();
private:
void entry();
};
SUBSTATE(Programmed, Operational) {
STATE(Programmed)
void minute();
void start();
};
SUBSTATE(Cooking, Programmed) {
STATE(Cooking)
void tick();
private:
void entry();
void exit();
};
void Top::init() {
setState<Operational>();
}
void Disabled::entry() {
cout << " Microwave opened" << endl;
}
void Disabled::exit() {
cout << " Microwave closed" << endl;
}
void Disabled::close() {
setStateHistory<Operational>();
}
void Operational::init() {
setState<Idle>();
}
void Operational::open() {
setState<Disabled>();
}
void Operational::stop() {
setState<Idle>();
}
void Idle::entry() {
TOP::box().resetTimer();
cout << " Microwave ready" << endl;
}
void Idle::minute() {
setState<Programmed>();
dispatch(Event(&TOP::minute));
}
void Programmed::minute() {
TOP::box().incrementTimer();
TOP::box().printTimer();
}
void Programmed::start() {
setState<Cooking>();
}
void Cooking::entry() {
cout << " Heating on" << endl;
}
void Cooking::exit() {
cout << " Heating off" << endl;
}
void Cooking::tick() {
cout << " Clock tick" << endl;
TOP::Box & tb = TOP::box();
tb.decrementTimer();
if (tb.getRemainingTime() == 0) {
cout << " Finished" << endl;
setState<Idle>();
} else
tb.printTimer();
}
}
int main() {
Macho::Machine<Microwave::Top> m;
cout << "Lets cook ourself a TV dinner:" << endl;
m->minute();
m->minute();
m->minute();
m->start();
m->tick();
m->open();
cout << "Adding a little spice..." << endl;
m->close();
m->tick();
m->tick();
cout << "Now there is the remote...?" << endl;
return 0;
}