]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trainrouteplanner.h
Add a distance metric to turn the routing into an A* search
[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/time/timedelta.h>
7 #include "trackiter.h"
8
9 namespace R2C2 {
10
11 class Layout;
12 class Route;
13 class Track;
14 class Train;
15 class TrainRouter;
16
17 class TrainRoutePlanner
18 {
19 private:
20         struct TrainRoutingState;
21
22         struct TrainRoutingInfo
23         {
24                 Train *train;
25                 float speed;
26                 TrainRouter *router;
27                 Route *route;
28                 std::list<const TrainRoutingState *> waits;
29
30                 TrainRoutingInfo(Train &);
31         };
32
33         struct OccupiedTrack
34         {
35                 Track *track;
36                 float path_length;
37                 OccupiedTrack *next;
38                 unsigned n_tracks;
39                 unsigned refcount;
40
41                 OccupiedTrack(Track &, unsigned, OccupiedTrack *);
42                 OccupiedTrack(const OccupiedTrack &);
43                 ~OccupiedTrack();
44         };
45
46         enum TrainState
47         {
48                 MOVING,
49                 WAITING,
50                 BLOCKED,
51                 ARRIVED
52         };
53
54         struct TrainRoutingState
55         {
56                 TrainRoutingInfo *info;
57                 TrackIter track;
58                 unsigned path;
59                 OccupiedTrack *occupied_tracks;
60                 float offset;
61                 float back_offset;
62                 TrainState state;
63                 Msp::Time::TimeDelta delay;
64                 int waypoint;
65                 Msp::Time::TimeDelta remaining_estimate;
66                 int blocked_by;
67
68                 TrainRoutingState(TrainRoutingInfo &);
69                 TrainRoutingState(const TrainRoutingState &);
70                 ~TrainRoutingState();
71
72                 Msp::Time::TimeDelta get_time_to_next_track() const;
73                 bool is_occupying(Track &) const;
74                 bool check_arrival();
75                 void advance(float);
76                 void advance_track(unsigned);
77                 void update_estimate();
78         };
79
80         struct RoutingStep
81         {
82                 Msp::Time::TimeDelta time;
83                 Msp::Time::TimeDelta total_estimate;
84                 std::vector<TrainRoutingState> trains;
85                 const RoutingStep *prev;
86
87                 RoutingStep();
88                 RoutingStep(const RoutingStep *);
89
90                 void create_successors(std::list<RoutingStep> &) const;
91                 bool update_states();
92                 bool check_deadlocks() const;
93                 int get_occupant(Track &) const;
94                 int find_next_train() const;
95                 void advance(const Msp::Time::TimeDelta &);
96                 void update_estimate();
97                 bool is_viable() const;
98                 bool is_goal() const;
99
100                 bool operator<(const RoutingStep &) const;
101         };
102
103         std::vector<TrainRoutingInfo> routed_trains;
104         std::list<RoutingStep> steps;
105         std::list<RoutingStep> queue;
106
107 public:
108         TrainRoutePlanner(Layout &);
109
110         void plan();
111 private:
112         const RoutingStep &get_step();
113         void add_steps(const RoutingStep &);
114         void create_routes(const RoutingStep &);
115 };
116
117 } // namespace R2C2
118
119 #endif