-
Notifications
You must be signed in to change notification settings - Fork 176
/
elevator.cpp
115 lines (87 loc) · 2.42 KB
/
elevator.cpp
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
104
105
106
107
108
109
110
111
112
113
114
115
#include <tinyfsm.hpp>
#include "elevator.hpp"
#include "fsmlist.hpp"
#include <iostream>
class Idle; // forward declaration
// ----------------------------------------------------------------------------
// Transition functions
//
static void CallMaintenance() {
std::cout << "*** calling maintenance ***" << std::endl;
}
static void CallFirefighters() {
std::cout << "*** calling firefighters ***" << std::endl;
}
// ----------------------------------------------------------------------------
// State: Panic
//
class Panic
: public Elevator
{
void entry() override {
send_event(MotorStop());
}
};
// ----------------------------------------------------------------------------
// State: Moving
//
class Moving
: public Elevator
{
void react(FloorSensor const & e) override {
int floor_expected = current_floor + Motor::getDirection();
if(floor_expected != e.floor)
{
std::cout << "Floor sensor defect (expected " << floor_expected << ", got " << e.floor << ")" << std::endl;
transit<Panic>(CallMaintenance);
}
else
{
std::cout << "Reached floor " << e.floor << std::endl;
current_floor = e.floor;
if(e.floor == dest_floor)
transit<Idle>();
}
};
};
// ----------------------------------------------------------------------------
// State: Idle
//
class Idle
: public Elevator
{
void entry() override {
send_event(MotorStop());
}
void react(Call const & e) override {
dest_floor = e.floor;
if(dest_floor == current_floor)
return;
/* lambda function used for transition action */
auto action = [] {
if(dest_floor > current_floor)
send_event(MotorUp());
else if(dest_floor < current_floor)
send_event(MotorDown());
};
transit<Moving>(action);
};
};
// ----------------------------------------------------------------------------
// Base state: default implementations
//
void Elevator::react(Call const &) {
std::cout << "Call event ignored" << std::endl;
}
void Elevator::react(FloorSensor const &) {
std::cout << "FloorSensor event ignored" << std::endl;
}
void Elevator::react(Alarm const &) {
transit<Panic>(CallFirefighters);
}
int Elevator::current_floor = Elevator::initial_floor;
int Elevator::dest_floor = Elevator::initial_floor;
// ----------------------------------------------------------------------------
// Initial state definition
//
FSM_INITIAL_STATE(Elevator, Idle)