std::string account;
mutable messaging::sender atm_queue;
get_balance(
std::string const& account_, messaging::sender atm_queue_):
account(account_), atm_queue(atm_queue_) {}
};
struct balance {
unsigned amount;
explicit balance(unsigned amount_):
amount(amount_) {}
};
struct display_balance {
unsigned amount;
explicit display_balance(unsigned amount_):
amount(amount_) {}
};
struct balance_pressed {};
Листинг С.7.Конечный автомат банкомата
class atm {
messaging::receiver incoming;
messaging::sender bank;
messaging::sender interface_hardware;
void (atm::*state)();
std::string account;
unsigned withdrawal_amount;
std::string pin;
void process_withdrawal() {
incoming.wait().handle(
[&](withdraw_ok const& msg) {
interface_hardware.send(
issue_money(withdrawal_amount));
bank.send(
withdrawal_processed(account, withdrawal_amount));
state = &atm::done_processing;
}
).handle(
[&](withdraw_denied const& msg) {
interface_hardware.send(display_insufficient_funds());
state = &atm::done_processing;
}
).handle(
[&](cancel_pressed const& msg) {
bank.send(
cancel_withdrawal(account, withdrawal_amount));
interface_hardware.send(
display_withdrawal_cancelled());
state = &atm::done_processing;
}
);
}
void process_balance() {
incoming.wait().handle(
[&](balance const& msg) {
interface_hardware.send(display_balance(msg.amount));
state = &atm::wait_for_action;
}
).handle(
[&](cancel_pressed const& msg) {
state = &atm::done_processing;
}
);
}
void wait_for_action() {
interface_hardware.send(display_withdrawal_options());
incoming.wait().handle(
[&](withdraw_pressed const& msg) {
withdrawal_amount = msg.amount;
bank.send(withdraw(account, msg.amount, incoming));
state = &atm::process_withdrawal;
}
).handle(
[&](balance_pressed const& msg) {
bank.send(get_balance(account, incoming));
state = &atm::process_balance;
}
).handle(
[&](cancel_pressed const& msg) {
state = &atm::done_processing;
}
);
}
void verifying_pin() {
incoming.wait().handle(
[&](pin_verified const& msg) {
state = &atm::wait_for_action;
}
).handle(
[&](pin_incorrect const& msg) {
interface_hardware.send(
display_pin_incorrect_message());
state = &atm::done_processing;
}
).handle(
[&](cancel_pressed const& msg) {
state = &atm::done_processing;
}
);
}
void getting_pin() {
incoming.wait().handle(
[&](digit_pressed const& msg) {
unsigned const pin_length = 4;
pin += msg.digit;
if (pin.length() == pin_length) {
bank.send(verify_pin(account, pin, incoming));
state = &atm::verifying_pin;
}
}
).handle(
[&](clear_last_pressed const& msg) {
if (!pin.empty()) {
pin.pop_back();
}
}
).handle(
[&](cancel_pressed const& msg) {
state = &atm::done_processing;
}
);
}
void waiting_for_card() {
interface_hardware.send(display_enter_card());
incoming.wait().handle(
[&](card_inserted const& msg) {
account = msg.account;
pin = "";
interface_hardware.send(display_enter_pin());
state = &atm::getting_pin;
}
);
}
void done_processing() {
interface_hardware.send(eject_card());
state = &atm::waiting_for_card;
}
atm(atm const&) = delete;
atm& operator=(atm const&) = delete;
public:
atm(messaging::sender bank_,
messaging::sender interface_hardware_):
bank(bank_), interface_hardware(interface_hardware_) {}
void done() {
get_sender().send(messaging::close_queue());
}
void run() {
state = &atm::waiting_for_card;
try {
for (;;) {
(this->*state)();
}
} catch(messaging::close_queue const&) {
}
}
messaging::sender get_sender() {
return incoming;
}
};
Листинг С.8.Конечный автомат банка
class bank_machine {
messaging::receiver incoming;
unsigned balance;
public:
bank_machine():
balance(199) {}
void done() {
get_sender().send(messaging::close_queue());
}
void run() {
try {
for (;;) {
incoming.wait().handle(
[&](verify_pin const& msg) {
if (msg.pin == "1937") {
msg.atm_queue.send(pin_verified());
} else {
msg.atm_queue.send(pin_incorrect());
}
}
).handle(
[&](withdraw const& msg) {
if (balance >= msg.amount) {
msg.atm_queue.send(withdraw_ok());
balance -= msg.amount;
} else {
msg.atm_queue.send(withdraw_denied());
}
}
).handle(
[&](get_balance const& msg) {
msg.atm_queue.send(::balance(balance));
}
).handle(
[&](withdrawal_processed const& msg) {
}
).handle(
[&](cancel_withdrawal const& msg) {
}
);
Читать дальше