Created
September 6, 2017 15:05
-
-
Save schmalz/3061d1defc968972212d4f84d817b3a2 to your computer and use it in GitHub Desktop.
Designing for Scalability with Erlang/OTP - Ch 6 - Coffee FSM - LFE + OTP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defmodule coffee-fsm | |
(behaviour gen_fsm) | |
(export | |
(start-link 0) | |
(stop 0) | |
(handle_sync_event 4) | |
(init 1) | |
(terminate 3) | |
(selection 2) | |
(payment 2) | |
(remove 2) | |
(tea 0) | |
(espresso 0) | |
(americano 0) | |
(cappuccino 0) | |
(pay 1) | |
(cup-removed 0) | |
(cancel 0))) | |
(defun server-name () | |
(MODULE)) | |
(defun callback-module () | |
(MODULE)) | |
(defun initial-data () | |
'()) | |
(defun opts () | |
'()) | |
(defun register-name () | |
`#(local ,(server-name))) | |
(defun start-link () | |
(gen_fsm:start_link (register-name) (callback-module) (initial-data) (opts))) | |
(defun init (_) | |
(hw:reboot) | |
(hw:display "make your selection" '()) | |
(process_flag 'trap_exit 'true) | |
#(ok selection ())) | |
(defun stop () | |
(gen_fsm:sync_send_all_state_event (MODULE) 'stop)) | |
(defun tea () | |
(gen_fsm:send_event (MODULE) #(selection tea 100))) | |
(defun espresso () | |
(gen_fsm:send_event (MODULE) #(selection espresso 150))) | |
(defun americano () | |
(gen_fsm:send_event (MODULE) #(selection americano 100))) | |
(defun cappuccino () | |
(gen_fsm:send_event (MODULE) #(selection cappuccino 150))) | |
(defun cup-removed () | |
(gen_fsm:send_event (MODULE) 'cup-removed)) | |
(defun pay (coin) | |
(gen_fsm:send_event (MODULE) `#(pay ,coin))) | |
(defun cancel () | |
(gen_fsm:send_event (MODULE) 'cancel)) | |
(defun selection | |
((`#(selection ,brew ,price) _data) | |
(hw:display "please pay ~w" `(,price)) | |
`#(next_state payment ,`#(,brew ,price 0))) | |
((`#(pay ,coin) data) | |
(hw:return-change coin) | |
`#(next_state selection ,data)) | |
((_other data) | |
`#(next_state selection ,data))) | |
(defun payment | |
((`#(pay ,coin) `#(,brew ,price ,paid)) | |
(when (< (+ coin paid) price)) | |
(let ((paid (+ paid coin))) | |
(hw:display "please pay ~w" `(,(- price paid))) | |
`#(next_state payment ,`#(,brew ,price ,paid)))) | |
((`#(pay ,coin) `#(,brew ,price ,paid)) | |
(when (>= (+ coin paid) price)) | |
(let ((paid (+ paid coin))) | |
(dispense brew price paid) | |
`#(next_state remove ()))) | |
(('cancel `#(,_brew ,_price ,paid)) | |
(hw:display "make your selection" '()) | |
(hw:return-change paid) | |
#(next_state selection ())) | |
((_other data) | |
`#(next_state payment ,data))) | |
(defun remove | |
(('cup-removed data) | |
(hw:display "make your selection" '()) | |
#(next_state selection ())) | |
((`#(pay ,coin) data) | |
(hw:return-change coin) | |
#(next_state remove ())) | |
((_other data) | |
#(next_state remove ()))) | |
(defun handle_sync_event | |
(('stop _from _state data) | |
`#(stop normal ,data))) | |
(defun terminate | |
((_reason 'payment `#(,_brew ,_price ,paid)) | |
(when (> paid 0)) | |
(hw:return-change paid)) | |
((_reason _state _data) | |
'ok)) | |
(defun dispense (brew price paid) | |
(hw:display "preparing drink" '()) | |
(if (> paid price) | |
(hw:return-change (- paid price))) | |
(hw:drop-cup) | |
(hw:prepare brew) | |
(hw:display "remove drink" '())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And this is the coffee example, written to use
gen_fsm
.It re-uses the hw file.