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) {