-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtraffic.adb
168 lines (145 loc) · 5.62 KB
/
traffic.adb
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
with Ada.Characters.Latin_1;
with Ada.Numerics.Float_Random;
with Ada.Text_IO;
procedure Traffic is
type Vehicle_IDs is range 0 .. 9;
type Number_Plate is access String;
type Lamp_Color is
(Red,
Red_Yellow,
Green,
Yellow);
protected Crossroads is
entry Cross (Time : Duration);
procedure Wake_Up;
end Crossroads;
protected Multi_Printer is
entry Init;
entry Get_Time_To_Cross (Time : out Duration;
Offset : in Duration);
procedure Print_Lamp_Color (Color : Lamp_Color);
procedure Print_Vehicle_Status (Plate : in Number_Plate;
Message : in String);
private
G : Ada.Numerics.Float_Random.Generator;
Initialized : Boolean := False;
end Multi_Printer;
protected Lamp is
function Color return Lamp_Color;
procedure Switch;
private
Curr_Color : Lamp_Color := Red;
end Lamp;
task type Signal;
type Signal_Access is access Signal;
task Controller is
entry Stop;
end Controller;
task type Vehicle (Plate : Number_Plate);
task body Vehicle is
Cross_Duration : Duration;
begin
Multi_Printer.Print_Vehicle_Status (Plate, "keresztezodeshez ert");
Multi_Printer.Get_Time_To_Cross (Cross_Duration, 0.5);
select
Crossroads.Cross (Cross_Duration);
else
Multi_Printer.Get_Time_To_Cross (Cross_Duration, 2.5);
Crossroads.Cross (Cross_Duration);
end select;
Multi_Printer.Print_Vehicle_Status (Plate, "atert a keresztezodesen " &
Duration'Image (Cross_Duration) & " sec alatt.");
if Vehicle_IDs'Value (Plate.all) = Vehicle_IDs'Last then
Controller.Stop;
end if;
end Vehicle;
-- a szimulacionak valoszinuleg egybol veget kellene ernie, ha `controller.stop`-ot
-- meghivjak (jobb oldali, kommentkent szereplo kod), nem csak akkor a kovetkezo
-- lampa szinenek megvaltozasakor (bal oldali kod), de itt hagyom mindkettot,
-- mert a feladat szovege alapjan egyik mukodes sem hibas
task body Controller is
Curr_Color : Lamp_Color;
begin -- begin
loop -- loop
select -- Curr_Color := Lamp.Color;
accept Stop; -- case Curr_Color is
exit; -- when Red | Green => Curr_Wait_Time := 3.0;
else -- when Red_Yellow => Curr_Wait_Time := 1.0;
Curr_Color := Lamp.Color; -- when Yellow => Curr_Wait_Time := 2.0;
case Curr_Color is -- end case;
when Red | Green => delay 3.0; -- select
when Red_Yellow => delay 1.0; -- accept Stop;
when Yellow => delay 2.0; -- exit;
end case; -- or
Lamp.Switch; -- delay Curr_Wait_Time;
end select; -- end select;
end loop; -- end loop;
end Controller; -- end Controller;
task body Signal is
begin
Crossroads.Wake_Up;
end Signal;
protected body Lamp is
function Color return Lamp_Color is
begin
return Curr_Color;
end Color;
procedure Switch is
S : Signal_Access;
begin
if Curr_Color = Lamp_Color'Last then
Curr_Color := Lamp_Color'First;
else
Curr_Color := Lamp_Color'Succ (Curr_Color);
end if;
Multi_Printer.Print_Lamp_Color (Curr_Color);
S := new Signal;
end Switch;
end Lamp;
protected body Multi_Printer is
entry Init
when not Initialized is
begin
Ada.Numerics.Float_Random.Reset (G);
Initialized := True;
end Init;
entry Get_Time_To_Cross (Time : out Duration;
Offset : in Duration)
when Initialized is
begin
Time := Offset + Duration (Ada.Numerics.Float_Random.Random (G));
end Get_Time_To_Cross;
procedure Print_Lamp_Color (Color : in Lamp_Color) is
begin
Ada.Text_IO.Put_Line ("A lampa: " & Lamp_Color'Image (Color));
end Print_Lamp_Color;
procedure Print_Vehicle_Status (Plate : in Number_Plate;
Message : in String) is
begin
Ada.Text_IO.Put_Line (Ada.Characters.Latin_1.HT & Plate.all & " " &
Message);
end Print_Vehicle_Status;
end Multi_Printer;
protected body Crossroads is
entry Cross (Time : Duration)
when Lamp.Color = Green is
begin
delay Time;
end Cross;
procedure Wake_Up is
begin
null;
end Wake_Up;
end Crossroads;
V : access Vehicle;
begin
Multi_Printer.Init;
for I in Vehicle_IDs'Range loop
V := new Vehicle (new String'(Vehicle_IDs'Image (I)));
delay 0.5;
end loop;
delay 10.0;
if not Controller'Terminated then
Controller.Stop;
end if;
end Traffic;