188 lines
5.4 KiB
C++
188 lines
5.4 KiB
C++
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>(
|
|
[&](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>(
|
|
[&](withdraw_denied const& msg)
|
|
{
|
|
interface_hardware.send(display_insufficient_funds());
|
|
state=&atm::done_processing;
|
|
}
|
|
)
|
|
.handle<cancel_pressed>(
|
|
[&](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>(
|
|
[&](balance const& msg)
|
|
{
|
|
interface_hardware.send(display_balance(msg.amount));
|
|
state=&atm::wait_for_action;
|
|
}
|
|
)
|
|
.handle<cancel_pressed>(
|
|
[&](cancel_pressed const& msg)
|
|
{
|
|
state=&atm::done_processing;
|
|
}
|
|
);
|
|
}
|
|
void wait_for_action()
|
|
{
|
|
interface_hardware.send(display_withdrawal_options());
|
|
incoming.wait()
|
|
.handle<withdraw_pressed>(
|
|
[&](withdraw_pressed const& msg)
|
|
{
|
|
withdrawal_amount=msg.amount;
|
|
bank.send(withdraw(account,msg.amount,incoming));
|
|
state=&atm::process_withdrawal;
|
|
}
|
|
)
|
|
.handle<balance_pressed>(
|
|
[&](balance_pressed const& msg)
|
|
{
|
|
bank.send(get_balance(account,incoming));
|
|
state=&atm::process_balance;
|
|
}
|
|
)
|
|
.handle<cancel_pressed>(
|
|
[&](cancel_pressed const& msg)
|
|
{
|
|
state=&atm::done_processing;
|
|
}
|
|
);
|
|
}
|
|
void verifying_pin()
|
|
{
|
|
incoming.wait()
|
|
.handle<pin_verified>(
|
|
[&](pin_verified const& msg)
|
|
{
|
|
state=&atm::wait_for_action;
|
|
}
|
|
)
|
|
.handle<pin_incorrect>(
|
|
[&](pin_incorrect const& msg)
|
|
{
|
|
interface_hardware.send(
|
|
display_pin_incorrect_message());
|
|
state=&atm::done_processing;
|
|
}
|
|
)
|
|
.handle<cancel_pressed>(
|
|
[&](cancel_pressed const& msg)
|
|
{
|
|
state=&atm::done_processing;
|
|
}
|
|
);
|
|
}
|
|
void getting_pin()
|
|
{
|
|
incoming.wait()
|
|
.handle<digit_pressed>(
|
|
[&](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>(
|
|
[&](clear_last_pressed const& msg)
|
|
{
|
|
if(!pin.empty())
|
|
{
|
|
pin.pop_back();
|
|
}
|
|
}
|
|
)
|
|
.handle<cancel_pressed>(
|
|
[&](cancel_pressed const& msg)
|
|
{
|
|
state=&atm::done_processing;
|
|
}
|
|
);
|
|
}
|
|
void waiting_for_card()
|
|
{
|
|
interface_hardware.send(display_enter_card());
|
|
incoming.wait()
|
|
.handle<card_inserted>(
|
|
[&](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;
|
|
}
|
|
};
|