]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trainrouteplanner.h
Penalize steps other than the fastest one
[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 speed;
35                 TrainRouter *router;
36                 const TrackChain *destination;
37                 std::vector<const TrackChain *> waypoints;
38                 std::vector<const TrainRouteMetric *> metrics;
39                 bool has_duration;
40                 std::list<Route *> routes;
41                 Track *track_history[2];
42                 std::list<TrainRouter::SequencePoint> sequence;
43
44                 TrainRoutingInfo(Train &);
45         };
46
47         struct OccupiedTrack
48         {
49                 Track *track;
50                 float path_length;
51                 OccupiedTrack *next;
52                 unsigned n_tracks;
53                 unsigned refcount;
54
55                 OccupiedTrack(Track &, unsigned, OccupiedTrack *);
56                 OccupiedTrack(const OccupiedTrack &);
57                 ~OccupiedTrack();
58         };
59
60         enum TrainState
61         {
62                 MOVING,
63                 WAITING,
64                 BLOCKED,
65                 ARRIVED
66         };
67
68         struct TrainRoutingState
69         {
70                 TrainRoutingInfo *info;
71                 TrackIter track;
72                 unsigned path;
73                 OccupiedTrack *occupied_tracks;
74                 float offset;
75                 float back_offset;
76                 TrainState state;
77                 Msp::Time::TimeDelta delay;
78                 Msp::Time::TimeDelta duration;
79                 int waypoint;
80                 float distance_traveled;
81                 float remaining_estimate;
82                 Msp::Time::TimeDelta wait_time;
83                 int blocked_by;
84
85                 TrainRoutingState(TrainRoutingInfo &);
86                 TrainRoutingState(const TrainRoutingState &);
87                 ~TrainRoutingState();
88
89                 Msp::Time::TimeDelta get_time_to_next_track() const;
90                 bool is_occupying(Track &) const;
91                 bool check_arrival();
92                 void advance(float);
93                 void advance(const Msp::Time::TimeDelta &);
94                 void advance_track(unsigned);
95                 void update_estimate();
96         };
97
98         struct RoutingStep
99         {
100                 Msp::Time::TimeDelta time;
101                 Msp::Time::TimeDelta penalty;
102                 Msp::Time::TimeDelta cost_estimate;
103                 std::vector<TrainRoutingState> trains;
104                 const RoutingStep *prev;
105
106                 RoutingStep();
107                 RoutingStep(const RoutingStep *);
108
109                 void create_successors(std::list<RoutingStep> &) const;
110                 bool update_states();
111                 bool check_deadlocks() const;
112                 int get_occupant(Track &) const;
113                 int find_next_train() const;
114                 void advance(const Msp::Time::TimeDelta &);
115                 void update_estimate();
116                 bool is_viable() const;
117                 bool is_goal() const;
118
119                 bool operator<(const RoutingStep &) const;
120         };
121
122         class PlanningThread: public Msp::Thread
123         {
124         private:
125                 TrainRoutePlanner &planner;
126
127         public:
128                 PlanningThread(TrainRoutePlanner &);
129
130         private:
131                 virtual void main();
132         };
133
134         std::vector<TrainRoutingInfo> routed_trains;
135         std::list<RoutingStep> steps;
136         std::list<RoutingStep> queue;
137         const RoutingStep *goal;
138         Result result;
139         PlanningThread *thread;
140
141 public:
142         TrainRoutePlanner(Layout &);
143         ~TrainRoutePlanner();
144
145         Result plan();
146         void plan_async();
147         Result check();
148         Result get_result() { return result; }
149         const std::list<Route *> &get_routes_for(const Train &) const;
150         const std::list<TrainRouter::SequencePoint> &get_sequence_for(const Train &) const;
151 private:
152         const TrainRoutingInfo &get_train_info(const Train &) const;
153         const RoutingStep &get_step();
154         void prepare_plan();
155         void create_plan();
156         void add_steps(const RoutingStep &);
157         void finalize_plan();
158 };
159
160 } // namespace R2C2
161
162 #endif