]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trainrouteplanner.h
Penalize running against the preferred direction when planning routes
[r2c2.git] / source / libr2c2 / trainrouteplanner.h
1 #ifndef LIBR2C2_TRAINROUTEPLANNER_H_
2 #define LIBR2C2_TRAINROUTEPLANNER_H_
3
4 #include <list>
5 #include <vector>
6 #include <msp/core/thread.h>
7 #include <msp/time/timedelta.h>
8 #include "trackiter.h"
9 #include "trainrouter.h"
10
11 namespace R2C2 {
12
13 class Layout;
14 class Route;
15 class Track;
16 class Train;
17
18 class TrainRoutePlanner
19 {
20 public:
21         enum Result
22         {
23                 PENDING,
24                 COMPLETE,
25                 FAILED
26         };
27
28 private:
29         struct TrainRoutingState;
30
31         struct TrainRoutingInfo
32         {
33                 Train *train;
34                 float length;
35                 float speed;
36                 Block *first_noncritical;
37                 TrainRouter *router;
38                 std::vector<TrainRouter::Waypoint> waypoints;
39                 std::vector<const TrainRouteMetric *> metrics;
40                 bool has_duration;
41                 std::list<Route *> routes;
42                 Track *track_history[2];
43                 std::list<TrainRouter::SequencePoint> sequence;
44
45                 TrainRoutingInfo(Train &);
46         };
47
48         struct OccupiedTrack
49         {
50                 Track *track;
51                 float path_length;
52                 OccupiedTrack *next;
53                 unsigned n_tracks;
54                 unsigned refcount;
55
56                 OccupiedTrack(Track &, unsigned, OccupiedTrack *);
57                 OccupiedTrack(const OccupiedTrack &);
58                 ~OccupiedTrack();
59         };
60
61         enum TrainState
62         {
63                 MOVING,
64                 WAITING,
65                 BLOCKED,
66                 ARRIVED
67         };
68
69         struct TrainRoutingState
70         {
71                 TrainRoutingInfo *info;
72                 TrackIter track;
73                 unsigned char path;
74                 bool critical;
75                 OccupiedTrack *occupied_tracks;
76                 float offset;
77                 float back_offset;
78                 TrainState state;
79                 Msp::Time::TimeDelta delay;
80                 Msp::Time::TimeDelta duration;
81                 unsigned waypoint;
82                 float travel_multiplier;
83                 float distance_traveled;
84                 float remaining_estimate;
85                 Msp::Time::TimeDelta wait_time;
86                 Msp::Time::TimeDelta estimated_wait;
87                 int blocked_by;
88
89                 TrainRoutingState(TrainRoutingInfo &);
90                 TrainRoutingState(const TrainRoutingState &);
91                 ~TrainRoutingState();
92
93                 Msp::Time::TimeDelta get_time_to_next_track() const;
94                 Msp::Time::TimeDelta get_time_to_pass(Track &) const;
95                 bool is_occupying(Track &) const;
96                 bool check_arrival();
97                 void advance(float);
98                 void advance(const Msp::Time::TimeDelta &);
99                 void advance_track(unsigned);
100                 void set_path(unsigned);
101                 void update_estimate();
102                 bool is_viable() const;
103         };
104
105         struct RoutingStep
106         {
107                 Msp::Time::TimeDelta time;
108                 Msp::Time::TimeDelta cost_estimate;
109                 bool preferred;
110                 std::vector<TrainRoutingState> trains;
111                 const RoutingStep *prev;
112
113                 RoutingStep();
114                 RoutingStep(const RoutingStep *);
115
116                 void create_successors(std::list<RoutingStep> &) const;
117                 static void create_successor(RoutingStep &, unsigned, unsigned, std::list<RoutingStep> &);
118                 bool update_states();
119                 bool check_deadlocks() const;
120                 int get_occupant(Track &) const;
121                 int find_next_train() const;
122                 void advance(const Msp::Time::TimeDelta &);
123                 void update_estimate();
124                 bool is_viable() const;
125                 bool is_goal() const;
126
127                 bool operator<(const RoutingStep &) const;
128         };
129
130         class PlanningThread: public Msp::Thread
131         {
132         private:
133                 TrainRoutePlanner &planner;
134
135         public:
136                 PlanningThread(TrainRoutePlanner &);
137
138         private:
139                 virtual void main();
140         };
141
142         std::vector<TrainRoutingInfo> routed_trains;
143         std::list<RoutingStep> steps;
144         std::list<RoutingStep> queue;
145         const RoutingStep *goal;
146         Msp::Time::TimeDelta path_switch_bias;
147         Msp::Time::TimeDelta timeout;
148         Result result;
149         PlanningThread *thread;
150
151 public:
152         TrainRoutePlanner(Layout &);
153         ~TrainRoutePlanner();
154
155         void set_timeout(const Msp::Time::TimeDelta &);
156         Result plan();
157         void plan_async();
158         Result check();
159         Result get_result() const { return result; }
160         const std::list<Route *> &get_routes_for(const Train &) const;
161         const std::list<TrainRouter::SequencePoint> &get_sequence_for(const Train &) const;
162 private:
163         const TrainRoutingInfo &get_train_info(const Train &) const;
164         const RoutingStep &get_step();
165         void prepare_plan();
166         void create_plan();
167         void add_steps(const RoutingStep &);
168         void finalize_plan();
169 };
170
171 } // namespace R2C2
172
173 #endif