1 |
|
2 | States = require("../")
|
3 |
|
4 | Errors = require("error-doc").create()
|
5 | .define("CommunicationFailure")
|
6 | .define("BarginFailure")
|
7 | .define("ProgrammerError")
|
8 | .generate()
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | class BuyCarProcedure extends States
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | constructor:()->
|
19 | super()
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | @waitFor "startSignal",()=>
|
25 |
|
26 |
|
27 | @setState "gotoShop"
|
28 | atGotoShop:(sole)->
|
29 | @waitFor "shopName",(name)=>
|
30 | @data.shopName = name
|
31 | @walkToShop name,(err)=>
|
32 |
|
33 |
|
34 | if not @checkSole sole
|
35 | return
|
36 |
|
37 | if err
|
38 | @error err
|
39 | return
|
40 | @setState "thinkOfAStartPrice"
|
41 | atThinkOfAStartPrice:()->
|
42 | @waitFor "startPrice",(price)=>
|
43 | @data.myPrice = price
|
44 | @setState "bargin"
|
45 | atBargin:(sole)->
|
46 | if not @data.myPrice
|
47 | @setState "thinkOfAStartPrice"
|
48 | return
|
49 | @bargin @data.myPrice,(err,result)=>
|
50 | if not @checkSole sole
|
51 | return
|
52 | if err
|
53 | @error err
|
54 | return
|
55 | if not result
|
56 | @data.myPrice += 100
|
57 | @setState "bargin"
|
58 | else
|
59 | @setState "pay"
|
60 | atPay:(sole)->
|
61 | @waitFor "money",(money)=>
|
62 | @pay money,(err)=>
|
63 | if not @checkSole sole
|
64 | return
|
65 | if err
|
66 | @error err
|
67 | return
|
68 | @setState "paid"
|
69 | atPaid:()->
|
70 | @emit "paid"
|
71 |
|
72 |
|
73 |
|
74 | walkToShop:(name,callback)->
|
75 | console.log "I walk to #{name} to buy a car"
|
76 | setTimeout callback,10
|
77 | bargin:(price,callback)->
|
78 | accept = 1000
|
79 | err = null
|
80 | console.log "I bid at price #{price}"
|
81 | if Math.random() > 0.85
|
82 | err = new Errors.CommunicationFailure("the manager say something I don't understand")
|
83 | else if Math.random() > 0.8
|
84 | err = new Errors.BarginFailure("the manager don't want to bargin with me any more")
|
85 | callback err,price > accept
|
86 | pay:(money,callback)->
|
87 | console.log "#{money} is given away."
|
88 | callback null
|
89 |
|
90 |
|
91 |
|
92 | p = new BuyCarProcedure()
|
93 |
|
94 | p.debug({name:"BuyCar"})
|
95 |
|
96 |
|
97 | p.on "wait/shopName",()=>
|
98 | p.give("shopName","the car shop near my house")
|
99 | p.on "wait/startPrice",()=>
|
100 | p.give("startPrice",500)
|
101 | p.on "wait/money",()=>
|
102 | p.give("money",p.data.myPrice + "$")
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | parentStateMachineData = {}
|
113 | d = parentStateMachineData
|
114 | p.on "panic",(err,state)=>
|
115 | if err instanceof Errors.CommunicationFailure and state is "bargin"
|
116 |
|
117 | p.recover()
|
118 | p.setState "bargin"
|
119 | else if err instanceof Errors.BarginFailure and state is "bargin"
|
120 | d.failCount ?= 0
|
121 | d.failCount++
|
122 | if d.failCount < 3
|
123 |
|
124 | p.recover()
|
125 | p.setState "bargin"
|
126 | else
|
127 |
|
128 | console.log "I can't bargin with this asshole any more!"
|
129 | process.exit(0)
|
130 | else
|
131 | throw new Errors.ProgrammerError("I don't expect this kind of situation",{via:err,state:state})
|
132 | p.on "paid",()->
|
133 | console.log "paid!"
|
134 |
|
135 | p.give("startSignal")
|