-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathelev_fsm.erl
103 lines (80 loc) · 1.94 KB
/
elev_fsm.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
-module(elev_fsm).
-export([start/1, event_new_order/1, event_floor_reached/1]).
%% Module Interface
%%%%%%%%%%%%%%%%%%%%
event_floor_reached(Pid) -> Pid ! floor_reached.
event_new_order(Pid) -> Pid ! new_order.
%% Call backs
%%%%%%%%%%%%%%%%%%%%%%%%
motor_up(Listener) -> Listener ! {motor, up}.
motor_down(Listener) -> Listener ! {motor, down}.
motor_stop(Listener) -> Listener ! {motor, stop}.
open_doors(Listener) -> Listener ! {doors, open}.
close_doors(Listener) -> Listener ! {doors, close}.
init_started(Listener) -> Listener ! {init, started}.
init_completed(Listener) -> Listener ! {init, completed}.
request_new_direction(Listener) ->
Listener ! {direction, request, self()},
receive
{direction, response, Direction} ->
Direction
end.
%% Process Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
start(Listener) ->
spawn(fun() -> state_init(Listener) end).
%% States
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
state_init(Listener) ->
flush(),
init_started(Listener),
receive
floor_reached ->
init_completed(Listener),
state_idle(Listener)
end.
state_driving_up(Listener) ->
flush(),
motor_up(Listener),
receive
floor_reached ->
state_idle(Listener)
end.
state_driving_down(Listener) ->
flush(),
motor_down(Listener),
receive
floor_reached ->
state_idle(Listener)
end.
state_idle(Listener) ->
flush(),
motor_stop(Listener),
NewDirection = request_new_direction(Listener),
case NewDirection of
up ->
state_driving_up(Listener);
down ->
state_driving_down(Listener);
open ->
state_open_doors(Listener);
stop ->
receive
new_order ->
state_idle(Listener)
end
end.
state_open_doors(Listener) ->
flush(),
open_doors(Listener),
timer:sleep(3000),
close_doors(Listener),
state_idle(Listener).
%% Helpers
%%%%%%%%
flush() ->
receive _Any ->
flush()
after 0 ->
ok
end.